* src/vm/jit/jit.c (jit_compile_intern): Perform inlining if
[cacao.git] / src / vm / jit / jit.h
index e252852820aa2fc5a1c3af756e8b0c41bc2be798..de45e2d222e0dfd9bc6412fc91291e66660c45c5 100644 (file)
 
    Authors: Andreas Krall
             Reinhard Grafl
+            Christian Thalinger
+            Edwin Steiner
 
-   Changes: Christian Thalinger
-                       Edwin Steiner
-
-   $Id: jit.h 5217 2006-08-08 12:46:51Z edwin $
+   $Id: jit.h 6211 2006-12-16 22:53:24Z edwin $
 
 */
 
@@ -46,8 +45,8 @@ typedef stackelement *stackptr;
 typedef struct basicblock basicblock;
 typedef struct branchref branchref;
 typedef struct instruction instruction;
-typedef struct new_instruction new_instruction;
 typedef struct insinfo_inline insinfo_inline;
+typedef struct exception_entry exception_entry;
 
 
 #include "config.h"
@@ -62,6 +61,7 @@ typedef struct insinfo_inline insinfo_inline;
 #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"
@@ -70,10 +70,15 @@ 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)
@@ -84,33 +89,68 @@ typedef struct insinfo_inline insinfo_inline;
 # define COUNT_SPILLS    /* nothing */
 #endif
 
+typedef struct interface_info interface_info;
+
+struct interface_info {
+       s4 flags;
+       s4 regoff;
+};
+
 
 /* jitdata ********************************************************************/
 
 struct jitdata {
-       methodinfo      *m;                 /* methodinfo of the method compiled  */
+       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;
+       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              *basicblockindex; /* block index for each JavaPC          */
+                                      /* valid between parse and stack        */
+       stackelement    *stack;           /* XXX should become stack.c internal   */
+       s4               instructioncount;/* XXX remove this?                     */
+       s4               basicblockcount; /* number of basic blocks               */
+       s4               stackcount;      /* number of stackelements to allocate  */
+                                      /* (passed from parse to stack)         */
+
+       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. */
+                           /* local_map[local_index * 5 + local_type] =          */
+                           /* new_index in rd->var or UNUSED                     */
+       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_VERIFY              0x00000002
 
@@ -118,6 +158,9 @@ struct jitdata {
 
 #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
@@ -139,6 +182,12 @@ struct jitdata {
 #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)
 
@@ -149,18 +198,46 @@ struct jitdata {
     ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
 
 
-/************************** stack element structure ***************************/
+/* macros for accessing variables *********************************************
+   Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
+   use VAR if you have the variable index (eg. VAR(iptr->sx.s23.s2.args[0])).
+
+******************************************************************************/
+
+#define VAROP(v) (jd->var + (v).varindex)
+#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 */
 
-#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 */
+#define SAVEDVAR      1         /* variable has to survive method invocations */
+#define INMEMORY      2         /* variable stored in memory                  */
+#define SAVREG        4         /* allocated to a saved register              */
+#define ARGREG        8         /* allocated to an arg register               */
+#define PASSTHROUGH  32         /* stackslot was passed-through by an ICMD    */
+#define PREALLOC     64         /* preallocated var like for ARGVARS. Used    */
+                                /* with the new var system */
+#define INOUT    128            /* variable is an invar or/and an outvar      */
+
+#define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
+#define IS_INMEMORY(x)    ((x) & INMEMORY)
+
 
 /* variable kinds */
 
@@ -173,14 +250,11 @@ struct jitdata {
 
 struct stackelement {
        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           */
 };
 
 
@@ -203,27 +277,27 @@ typedef struct {
 /*** s1 operand ***/
 
 typedef union {
-    stackptr                   var;
-    s4                         localindex;
+       s4                         varindex;
     s4                         argcount;
 } s1_operand_t;
 
 /*** s2 operand ***/
 
 typedef union {
-    stackptr                   var;
-    stackptr                  *args;
+       s4                         varindex;
+       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 ***/
 
 typedef union {
-    stackptr                   var;
+       s4                         varindex;
     ptrint                     constval;
     classref_or_classinfo      c;
     constant_FMIref           *fmiref;
@@ -233,6 +307,7 @@ typedef union {
     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;
 
@@ -251,54 +326,36 @@ typedef union {
 /*** dst operand ***/
 
 typedef union {
-    stackptr                   var;
-    s4                         localindex;
+       s4                         varindex;
     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_CLASS         0x02    /* for ACONST, PUT*CONST 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        */
+#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 ***/
 
-/* 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
@@ -318,35 +375,17 @@ struct new_instruction {
 #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 */
-
-#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) \
+#define INSTRUCTION_IS_UNRESOLVED(iptr) \
        ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
 
-#define NEW_INSTRUCTION_MUST_CHECK(iptr) \
-       (!((iptr)->flags.bits & INS_FLAG_NOCHECK))
+#define INSTRUCTION_MUST_CHECK(iptr) \
+       ((iptr)->flags.bits & INS_FLAG_CHECK)
 
-#define NEW_INSTRUCTION_GET_FIELDREF(iptr,fref) \
+#define INSTRUCTION_GET_FIELDREF(iptr,fref) \
        do { \
                if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
                        fref = iptr->sx.s23.s3.uf->fieldref; \
@@ -354,15 +393,7 @@ struct instruction {
                        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; \
@@ -370,23 +401,7 @@ struct instruction {
                        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; \
@@ -394,76 +409,37 @@ struct instruction {
                        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_CLASS(iptr) \
-       ((unresolved_class *) (iptr)->val.a)
-
-#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 ***************************/
 
 /* 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
@@ -485,18 +461,26 @@ struct insinfo_inline {
 /* combined without loss of efficiency. The first one could be combined with  */
 /* the others by using bitfields.                                             */
 
+/* XXX "flags" should probably be called "state", as it is an integer state   */
+
 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            lflags;       /* used during loop copying, init with 0      */
+
        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                */
+       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        */
        s4            outdepth;     /* stack depth end of basic block             */
+       s4            varstart;     /* index of first non-invar block variable    */
+       s4            varcount;     /* number of non-invar block variables        */
 
        s4            predecessorcount;
        s4            successorcount;
@@ -506,12 +490,14 @@ struct basicblock {
        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)                        */
+       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          */
 };
 
 
@@ -524,7 +510,6 @@ struct basicblock {
                bptr->flags  = -1;                             \
                bptr->type   = BBTYPE_STD;                     \
                bptr->method = (m);                            \
-               bptr->nr     = (m)->c_debug_nr++;              \
        } while (0)
                        
 
@@ -536,17 +521,88 @@ struct branchref {
 };
 
 
-/********** 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 ACONST_LOAD     0  /* ACONST_NULL or LDC instruction                  */
-#define ACONST_BUILTIN  1  /* constant argument for a builtin function call   */
+#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 ************************************************************/
+
+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
@@ -561,7 +617,6 @@ extern int jcommandsize[256];
 #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                   */
@@ -590,8 +645,10 @@ extern int jcommandsize[256];
 #define ICMD_DCONST           14        /* val.d = constant                   */
 
 #define JAVA_DCONST_1         15
+#define ICMD_COPY             15
 
 #define JAVA_BIPUSH           16
+#define ICMD_MOVE             16
 
 #define JAVA_SIPUSH           17
 
@@ -1183,15 +1240,11 @@ extern int jcommandsize[256];
 
 #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     */
@@ -1207,11 +1260,6 @@ extern int jcommandsize[256];
 #define PARAMMODE_STUFFED   1
 
 
-/***************************** register info block ****************************/
-
-extern int stackreq[256];
-
-
 /* function prototypes ********************************************************/
 
 /* compiler initialisation */
@@ -1220,15 +1268,27 @@ void jit_init(void);
 /* 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);