* src/mm/tlh.c (tlh_alloc): Correctly zero memory.
[cacao.git] / src / vm / jit / jit.h
index 51ba842261cb205401c604be44278242f107eee5..c447b1bd2db27018ba14c9e0eb2c7f3a6e3e4cc0 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/jit.h - code generation header
 
-   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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -31,8 +29,6 @@
 /* forward typedefs ***********************************************************/
 
 typedef struct jitdata jitdata;
-typedef struct stackelement stackelement;
-typedef stackelement *stackptr;
 typedef struct basicblock basicblock;
 typedef struct instruction instruction;
 typedef struct insinfo_inline insinfo_inline;
@@ -50,6 +46,7 @@ typedef struct exception_entry exception_entry;
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
+#include "vm/jit/stack.h"
 #include "vm/jit/stacktrace.h"
 
 #if defined(ENABLE_INLINING)
@@ -70,7 +67,6 @@ typedef struct exception_entry exception_entry;
 
 #include "vm/jit/verify/typeinfo.h"
 
-#include "vmcore/descriptor.h"
 #include "vmcore/method.h"
 #include "vmcore/references.h"
 
@@ -131,7 +127,7 @@ struct jitdata {
 
        instruction     *instructions;    /* ICMDs, valid between parse and stack */
        basicblock      *basicblocks;     /* start of basic block list            */
-       stackelement    *stack;           /* XXX should become stack.c internal   */
+       stackelement_t  *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  */
@@ -148,6 +144,9 @@ struct jitdata {
                         /*     >= 0......index into jd->var, or                  */
                                         /*     UNUSED....this (javaindex,type) pair is not used  */
 
+       s4              *reverselocalmap; /* map from CACAO varindex to javaindex */
+                                         /* (varindex must be < localcount)      */
+
        s4               maxlocals;       /* max. number of javalocals            */
 
        interface_info  *interface_map;   /* interface variables (for simplereg)  */
@@ -228,41 +227,6 @@ struct exception_entry {
 };
 
 
-/* stack element structure ****************************************************/
-
-/* flags */
-
-#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 */
-
-#define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
-#define TEMPVAR    1            /* stack slot is temp register                */
-#define STACKVAR   2            /* stack slot is numbered stack slot          */
-#define LOCALVAR   3            /* stack slot is local variable               */
-#define ARGVAR     4            /* stack slot is argument variable            */
-
-
-struct stackelement {
-       stackptr prev;              /* pointer to next element towards bottom     */
-       instruction *creator;       /* instruction that created this element      */
-       s4       type;              /* slot type of stack element                 */
-       s4       flags;             /* flags (SAVED, INMEMORY)                    */
-       s4       varkind;           /* kind of variable or register               */
-       s4       varnum;            /* number of variable                         */
-};
-
 /* macros for accessing variables *********************************************
  
    Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
@@ -283,7 +247,13 @@ static inline bool var_is_prealloc(const jitdata *jd, s4 i) {
 
 static inline bool var_is_inout(const jitdata *jd, s4 i) {
        const varinfo *v = jd->var + i;
-       return ((i >= jd->localcount) && !(v->flags & PREALLOC) && (v->flags & INOUT));
+       return (
+               (i >= jd->localcount) && (
+                       (!(v->flags & PREALLOC) && (v->flags & INOUT)) ||
+                       /* special case of TYPE_RET, used with JSR */
+                       ((v->flags & PREALLOC) && (v->flags & INOUT) && (v->type == TYPE_RET))
+               )
+       );
 }
 
 static inline bool var_is_temp(const jitdata *jd, s4 i) {
@@ -330,6 +300,7 @@ typedef union {
     s4                         tablelow;         /* for TABLESWITCH           */
     u4                         lookupcount;      /* for LOOKUPSWITCH          */
        s4                         retaddrnr;        /* for ASTORE                */
+       instruction              **iargs;            /* for PHI                   */
 } s2_operand_t;
 
 /*** s3 operand ***/
@@ -412,6 +383,9 @@ struct instruction {
 #if SIZEOF_VOID_P == 4
     flags_operand_t         flags;  /* 4 bytes      */
 #endif
+#if defined(ENABLE_ESCAPE_REASON)
+       void *escape_reasons;
+#endif
 };
 
 
@@ -558,7 +532,8 @@ struct basicblock {
        s4            expredecessorcount;
        s4            exouts;       /* Number of exceptional exits */
 
-       basicblock   *subbasicblocks;
+       instruction  *phis;         /* Phi functions */
+       s4            phicount;     /* Number of phi functions */
 
        void         *vp;           /* Freely used by different passes            */
 #endif
@@ -577,6 +552,9 @@ struct basicblock {
 #define FOR_EACH_INSTRUCTION(bptr, it) \
        for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
 
+#define FOR_EACH_INSTRUCTION_REV(bptr, it) \
+       for ((it) = (bptr)->iinstr + (bptr)->icount - 1; (it) != (bptr)->iinstr - 1; --(it))
+
 #if defined(ENABLE_SSA)
 
 #define FOR_EACH_EXHANDLER(bptr, it) \
@@ -984,6 +962,9 @@ enum {
        ICMD_IMULPOW2         = 214,
        ICMD_LMULPOW2         = 215,
 
+       ICMD_GETEXCEPTION     = 249,
+       ICMD_PHI              = 250,
+
        ICMD_INLINE_START     = 251,        /* instruction before inlined method  */
        ICMD_INLINE_END       = 252,        /* instruction after inlined method   */
        ICMD_INLINE_BODY      = 253,        /* start of inlined body              */
@@ -999,7 +980,7 @@ static inline bool instruction_has_dst(const instruction *iptr) {
        if (
                (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
                (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
-       ) {
+               ) {
                return instruction_call_site(iptr)->returntype.type != TYPE_VOID;
        } else {
                return icmd_table[iptr->opc].dataflow >= DF_DST_BASE;