Merged revisions 7501-7598 via svnmerge from
[cacao.git] / src / vm / jit / jit.h
index fdfe48829c5a07fc1522602c60ace58a9b2aea4e..fe5d3949c51a2d7922bc564c37f6e5bb57b3cb25 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 5769 2006-10-13 12:49:25Z edwin $
+   $Id: jit.h 7596 2007-03-28 21:05:53Z twisti $
 
 */
 
@@ -44,23 +36,21 @@ 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 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"
@@ -78,6 +68,15 @@ typedef struct insinfo_inline insinfo_inline;
 
 #include "vm/jit/verify/typeinfo.h"
 
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+#include "vm/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+
 /* common jit/codegen macros **************************************************/
 
 #if defined(ENABLE_STATISTICS)
@@ -99,7 +98,7 @@ struct interface_info {
 /* jitdata ********************************************************************/
 
 struct jitdata {
-       methodinfo      *m;                 /* methodinfo of the method compiled  */
+       methodinfo      *m;               /* methodinfo of the method compiled    */
        codeinfo        *code;
        codegendata     *cd;
        registerdata    *rd;
@@ -107,11 +106,11 @@ struct jitdata {
        loopdata        *ld;
 #endif
 #if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
-       lsradata     *ls;
+       lsradata        *ls;
 #endif
 
-       u4               flags;             /* contains JIT compiler flags        */
-       bool             isleafmethod;      /* does method call subroutines       */
+       u4               flags;           /* contains JIT compiler flags          */
+       bool             isleafmethod;    /* true, if no subroutines are called   */
 
        instruction     *instructions;    /* ICMDs, valid between parse and stack */
        basicblock      *basicblocks;     /* start of basic block list            */
@@ -122,20 +121,32 @@ struct jitdata {
        s4               basicblockcount; /* number of basic blocks               */
        s4               stackcount;      /* number of stackelements to allocate  */
                                       /* (passed from parse to stack)         */
-       s4               c_block_nr;      /* counter for basic block number       */
 
-       varinfo *var;                     /* array of variables                   */
-       s4      vartop;                   /* next free index in var array         */
+       varinfo         *var;             /* array of variables                   */
+       s4               vartop;          /* next free index in var array         */
     
-       s4      varcount;                 /* number of variables in var array     */
-       s4      localcount;               /* number of locals at start of var ar. */
-    s4      *local_map; /* internal structure to rename(de-coallesc) locals   */
-                           /* and keep the coalescing info for simplereg.        */
+       s4               varcount;        /* number of variables in var array     */
+       s4               localcount;      /* number of locals at start of var ar. */
+    s4              *local_map;  /* internal structure to rename(de-coallesc) */
+                                               /* locals and keep the coalescing info for simplereg. */
                            /* local_map[local_index * 5 + local_type] =          */
                            /* new_index in rd->var or UNUSED                     */
-       interface_info *interface_map;
+       s4               maxlocals;       /* max. number of javalocals            */
+
+       interface_info  *interface_map;   /* interface variables (for simplereg)  */
+       s4               maxinterfaces;   /* max. number of interface variables   */
+
+       s4               exceptiontablelength; /* exceptiontable length           */
+       exception_entry *exceptiontable;       /* the exceptiontable              */
+
+       basicblock      *returnblock;          /* block containing the *RETURN    */
+                                              /* (only use if returncount==1)    */
+       s4               returncount;          /* number of return instructions   */
+       bool             branchtoentry;        /* true if first block is a target */
+       bool             branchtoend;          /* true if end dummy is a target   */
 };
 
+
 #define UNUSED                     -1
 
 #define JITDATA_FLAG_PARSE               0x00000001
@@ -145,6 +156,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
@@ -166,6 +180,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)
 
@@ -187,6 +207,19 @@ struct jitdata {
 #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 */
@@ -217,13 +250,9 @@ 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           */
 };
 
 
@@ -254,12 +283,13 @@ typedef union {
 
 typedef union {
        s4                         varindex;
-       s4                         *args;
+       s4                        *args;
     classref_or_classinfo      c;
     unresolved_class          *uc;
     ptrint                     constval;         /* for PUT*CONST             */
     s4                         tablelow;         /* for TABLESWITCH           */
     u4                         lookupcount;      /* for LOOKUPSWITCH          */
+       s4                         retaddrnr;        /* for ASTORE                */
 } s2_operand_t;
 
 /*** s3 operand ***/
@@ -275,6 +305,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;
 
@@ -303,36 +334,19 @@ typedef union {
 /*** flags (32 bits) ***/
 
 #define INS_FLAG_UNRESOLVED    0x01    /* contains unresolved field/meth/class*/
-#define INS_FLAG_CLASS         0x02    /* for ACONST with class               */
+#define INS_FLAG_CLASS         0x02    /* for ACONST, PUT*CONST with class    */
 #define INS_FLAG_ARRAY         0x04    /* for CHECKCAST/INSTANCEOF with array */
 #define INS_FLAG_CHECK         0x08    /* for *ALOAD|*ASTORE: check index     */
                                        /* for BUILTIN: check exception        */
+#define INS_FLAG_KILL_PREV     0x02    /* for *STORE, invalidate prev local   */
+#define INS_FLAG_KILL_NEXT     0x04    /* for *STORE, invalidate next local   */
+#define INS_FLAG_RETADDR       0x08    /* for ASTORE: op is a returnAddress   */
+
+#define INS_FLAG_ID_SHIFT      4
+#define INS_FLAG_ID_MASK       (~0 << INS_FLAG_ID_SHIFT)
 
 typedef union {
     u4                  bits;
-    struct {         /* fields: */
-
-        union {
-            u1              type;         /* TYPE_* constant for fields       */
-            u1              argcount;     /* XXX does u1 suffice?             */
-                                          /* for MULTIANEWARRAY and           */
-                                          /* INVOKE*                          */
-        } f; /* XXX these could be made smaller */
-        /* only MULTIANEWARRAY needs the argcount */
-
-        bool                predicated:1;
-        int                 condition :3;
-        bool                unresolved:1; /* field/method is unresolved       */
-        bool                nocheck   :1; /* don't check array access         */
-        bool                branch    :1; /* branch to dst.target             */
-
-        int                 tmpreg1   :5;
-        int                 tmpreg2   :5;
-        int                 tmpreg3   :5;
-
-        int                 unused    :2;
-
-    } fields;
 } flags_operand_t;
 
 /*** instruction ***/
@@ -399,15 +413,33 @@ struct instruction {
 /* for ICMD_INLINE_START and ICMD_INLINE_END */
 
 struct insinfo_inline {
-       methodinfo *method;         /* the inlined method starting/ending here    */
-       methodinfo *outer;          /* the outer method suspended/resumed here    */
-       s4          startmpc;       /* machine code offset of start of inlining   */          
-       s4          synclocal;      /* local index used for synchronization       */
-       bool        synchronize;    /* true if synchronization is needed          */
+       /* fields copied from the inlining tree ----------------------------------*/
+       insinfo_inline *parent;     /* insinfo of the surrounding inlining, if any*/
+       methodinfo     *method;     /* the inlined method starting/ending here    */
+       methodinfo     *outer;      /* the outer method suspended/resumed here    */
+       s4              synclocal;      /* local index used for synchronization   */
+       bool            synchronize;    /* true if synchronization is needed      */
+       s4              throughcount;   /* total # of pass-through variables      */
+       s4              paramcount;     /* number of parameters of original call  */
+       s4              stackvarscount; /* source stackdepth at INLINE_START      */
+       s4             *stackvars;      /* stack vars at INLINE_START             */
+
+       /* fields set by inlining ------------------------------------------------*/
+       s4         *javalocals_start; /* javalocals at start of inlined body      */
+       s4         *javalocals_end;   /* javalocals after inlined body            */
+
+       /* fields set by replacement point creation ------------------------------*/
+#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
@@ -442,6 +474,7 @@ struct basicblock {
        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        */
@@ -462,6 +495,7 @@ struct basicblock {
        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          */
 };
@@ -476,18 +510,9 @@ struct basicblock {
                bptr->flags  = -1;                             \
                bptr->type   = BBTYPE_STD;                     \
                bptr->method = (m);                            \
-               bptr->nr     = (m)->c_block_nr++;              \
        } while (0)
                        
 
-/* branchref *****************************************************************/
-
-struct branchref {
-       s4         branchpos;       /* patching position in code segment          */
-       branchref *next;            /* next element in branchref list             */
-};
-
-
 /* data-flow constants for the ICMD table ************************************/
 
 #define DF_0_TO_0      0
@@ -565,16 +590,11 @@ struct icmdtable_entry_t {
 extern icmdtable_entry_t icmd_table[256];
 
 
-/********** op1 values for ACONST instructions ********************************/
-
-#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 *opcode_names[256];
 extern int jcommandsize[256];
+extern int stackreq[256];
 
 #define JAVA_NOP               0
 #define ICMD_NOP               0
@@ -589,7 +609,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                   */
@@ -1213,15 +1232,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     */
@@ -1237,18 +1252,6 @@ extern int jcommandsize[256];
 #define PARAMMODE_STUFFED   1
 
 
-/***************************** register info block ****************************/
-
-extern int stackreq[256];
-/* extern int op_needs_saved[256];  */
-/* extern int op_is_pei[256];       */
-#define NEEDS_SAVED  0
-#define PEI          1
-#define OP_DATA_SIZE 2
-extern int op_data[256][OP_DATA_SIZE]; 
-/* [0..255][NEEDS_SAVED] ... if ICMD needs a SAVEDVAR         */
-/* [0..255][PEI]         ... if ICMD could throw an exception */
-
 /* function prototypes ********************************************************/
 
 /* compiler initialisation */
@@ -1257,28 +1260,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);
 
 s4 jit_complement_condition(s4 opcode);
 
-/* 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
-
-#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 */