Merged revisions 8245-8298 via svnmerge from
[cacao.git] / src / vm / jit / jit.h
index 2fe41c4af1cffe62403133f5a9f1f2fcfdb044f9..a9dff9f3391bcb7769141d9f76e3ecfcdc69fa3a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/jit.h - code generation header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-                       Edwin Steiner
-
-   $Id: jit.h 5049 2006-06-23 12:07:26Z twisti $
+   $Id: jit.h 8295 2007-08-11 17:57:24Z michi $
 
 */
 
@@ -44,24 +36,22 @@ typedef struct jitdata jitdata;
 typedef struct stackelement stackelement;
 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"
 #include "vm/types.h"
 
 #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"
+#include "vm/jit/replace.h"
 
 #if defined(ENABLE_INLINING)
 # include "vm/jit/inline/inline.h"
@@ -70,27 +60,121 @@ 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"
 
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /* common jit/codegen macros **************************************************/
 
 #if defined(ENABLE_STATISTICS)
 # define COUNT(x)        (x)++
-# define COUNT_SPILLS    count_spills++
+# define COUNT_SPILLS             /* use COUNT_(READ|WRITE)_SPILLS instead */
+# define COUNT_READ_SPILLS(var) \
+       switch(var->type) { \
+       case TYPE_FLT: count_spills_read_flt++; break; \
+       case TYPE_DBL: count_spills_read_dbl++; break; \
+       default: count_spills_read_ila++; break; \
+       }
+
+# define COUNT_WRITE_SPILLS(var) \
+       switch(var->type) { \
+       case TYPE_FLT: count_spills_write_flt++; break; \
+       case TYPE_DBL: count_spills_write_dbl++; break; \
+       default: count_spills_write_ila++; break; \
+       }
+
 #else
-# define COUNT(x)        /* nothing */
-# define COUNT_SPILLS    /* nothing */
+# define COUNT(x)                /* nothing */
+# define COUNT_SPILLS            /* nothing */
+# define COUNT_READ_SPILLS(x)    /* nothing */
+# define COUNT_WRITE_SPILLS(x)   /* 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    */
+       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;    /* true, if no subroutines are called   */
+
+       instruction     *instructions;    /* ICMDs, valid between parse and stack */
+       basicblock      *basicblocks;     /* start of basic block list            */
+       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;       /* map for renaming (de-coallescing)    */
+                                        /* locals and keeping the coalescing info for simplereg. */
+                        /* local_map[javaindex * 5 + type] =                     */
+                        /*     >= 0......index into jd->var, or                  */
+                                        /*     UNUSED....this (javaindex,type) pair is not used  */
+
+       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
 
-#define JITDATA_FLAG_IFCONV              0x00000004
+#define JITDATA_FLAG_INSTRUMENT          0x00000004
+
+#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
@@ -103,9 +187,21 @@ typedef struct insinfo_inline insinfo_inline;
 #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_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)
 
@@ -116,60 +212,46 @@ typedef struct insinfo_inline insinfo_inline;
     ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
 
 
-struct jitdata {
-       methodinfo      *m;                 /* methodinfo of the method compiled  */
-       codeinfo        *code;
-       codegendata     *cd;
-       registerdata    *rd;
-#if defined(ENABLE_LOOP)
-       loopdata        *ld;
-#endif
-       u4               flags;             /* contains JIT compiler flags        */
-
-       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;
-};
+/* 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])).
 
+******************************************************************************/
 
-/************************** stack element structure ***************************/
+#define VAROP(v) (jd->var + (v).varindex)
+#define VAR(i)   (jd->var + (i))
 
-/* slot types */
 
-/* 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*/
+/* exception_entry ************************************************************/
 
-#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)
+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                  */
+};
 
-#define IS_INT_TYPE(a)          ((a) == TYPE_INT)
-#define IS_LNG_TYPE(a)          ((a) == TYPE_LNG)
-#define IS_ADR_TYPE(a)          ((a) == TYPE_ADR)
 
+/* 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 */
 
@@ -182,14 +264,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           */
 };
 
 
@@ -198,8 +277,8 @@ struct stackelement {
 /* branch_target_t: used in TABLESWITCH tables */
 
 typedef union {
-    s4                         insindex; /* used between parse and stack      */
-    basicblock                *block;    /* used from stack analysis onwards  */
+    s4                         insindex; /* used in parse                     */
+    basicblock                *block;    /* valid after parse                 */
 } branch_target_t;
 
 /* lookup_target_t: used in LOOKUPSWITCH tables */
@@ -212,27 +291,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;
@@ -242,6 +321,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;
 
@@ -253,61 +333,44 @@ typedef union {
     float                     f;
     double                    d;
     void                     *anyptr;
-    java_objectheader        *stringconst;       /* for ACONST with string    */
+    java_handle_t            *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     */
+       s4                         varindex;
+    basicblock                *block;       /* valid after parse              */
     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      */
+    s4                         insindex;    /* used in parse                  */
 } 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_BASICBLOCK    0x01    /* marks a basic block start           */
+#define INS_FLAG_UNRESOLVED    0x02    /* contains unresolved field/meth/class*/
+#define INS_FLAG_CLASS         0x04    /* for ACONST, PUT*CONST with class    */
+#define INS_FLAG_ARRAY         0x08    /* for CHECKCAST/INSTANCEOF with array */
+#define INS_FLAG_CHECK         0x10    /* for *ALOAD|*ASTORE: check index     */
+                                       /* for BUILTIN: check exception        */
+#define INS_FLAG_KILL_PREV     0x04    /* for *STORE, invalidate prev local   */
+#define INS_FLAG_KILL_NEXT     0x08    /* for *STORE, invalidate next local   */
+#define INS_FLAG_RETADDR       0x10    /* for ASTORE: op is a returnAddress   */
+
+#define INS_FLAG_ID_SHIFT      5
+#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
@@ -327,26 +390,20 @@ 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_STARTS_BASICBLOCK(iptr) \
+       ((iptr)->flags.bits & INS_FLAG_BASICBLOCK)
 
 #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 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 +411,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 +419,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,73 +427,39 @@ 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_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 ------------------------------*/
+#if defined(ENABLE_REPLACEMENT)
+       rplpoint   *rp;             /* replacement point at INLINE_START          */
+#endif
+
+       /* fields set by the codegen ---------------------------------------------*/
+       s4          startmpc;       /* machine code offset of start of inlining   */
 };
 
+
 /* basicblock *****************************************************************/
+
 /* flags */
 
 #define BBDELETED            -2
@@ -482,65 +481,159 @@ 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           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*/
+       s4            lflags;       /* used during loop copying, init with 0      */
+
+       s4            icount;       /* number of intermediate code instructions   */
+       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;
+       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) */
+       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               */
+       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          */
 };
 
-/* 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)
+/* [+]...the javalocals array: This array is indexed by the javaindex (the    */
+/*       local variable index ocurring in the original bytecode). An element  */
+/*       javalocals[javaindex] encodes where to find the contents of the      */
+/*       original variable at this point in the program.                      */
+/*       There are three cases for javalocals[javaindex]:                     */
+/*           >= 0.......it's an index into the jd->var array, where the       */
+/*                      CACAO variable corresponding to the original local    */
+/*                      can be found.                                         */
+/*           UNUSED.....the original variable is not live at this point       */
+/*           < UNUSED...the original variable contains a returnAddress at     */
+/*                      this point. The number of the block to return to can  */
+/*                      be calculated using RETADDR_FROM_JAVALOCAL:           */
+/*                                                                            */
+/*                      javalocals[javaindex] == JAVALOCAL_FROM_RETADDR(nr)   */
+/*                      RETADDR_FROM_JAVALOCAL(javalocals[javaindex]) == nr   */
+
+#define JAVALOCAL_FROM_RETADDR(nr)  (UNUSED - (1 + (nr)))
+#define RETADDR_FROM_JAVALOCAL(jl)  (UNUSED - (1 + (jl)))
+
+
+/* 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);                            \
+       } while (0)
                        
 
-/* branchref *****************************************************************/
+/* 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
 
-struct branchref {
-       s4         branchpos;       /* patching position in code segment          */
-       branchref *next;            /* next element in branchref list             */
+#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 */
 };
 
 
-/********** op1 values for ACONST instructions ********************************/
+/* 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
@@ -555,7 +648,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                   */
@@ -579,28 +671,23 @@ extern int jcommandsize[256];
 #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 ICMD_COPY             15
 
 #define JAVA_BIPUSH           16
-#define ICMD_IFNE_ICONST      16
+#define ICMD_MOVE             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   */
@@ -1184,19 +1271,10 @@ 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                    */
 
-/* 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 types *********************************/
 
@@ -1213,11 +1291,6 @@ extern int jcommandsize[256];
 #define PARAMMODE_STUFFED   1
 
 
-/***************************** register info block ****************************/
-
-extern int stackreq[256];
-
-
 /* function prototypes ********************************************************/
 
 /* compiler initialisation */
@@ -1226,26 +1299,25 @@ 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);
 
-/* machine dependent functions */
-#if defined(ENABLE_JIT)
-void md_init(void);
-
-u1  *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr);
-
-void md_cacheflush(u1 *addr, s4 nbytes);
-void md_icacheflush(u1 *addr, s4 nbytes);
-void md_dcacheflush(u1 *addr, s4 nbytes);
-#endif
+s4 jit_complement_condition(s4 opcode);
 
-#if defined(ENABLE_INTRP)
-void intrp_md_init(void);
+void jit_renumber_basicblocks(jitdata *jd);
+#if !defined(NDEBUG)
+void jit_check_basicblock_numbers(jitdata *jd);
 #endif
 
 #endif /* _JIT_H */