* src/mm/memory.cpp,
[cacao.git] / src / vm / jit / allocator / simplereg.c
index cb7d743f473829af359d6d1bc2d8d3e28f866f9d..f3390ba045c9e96125824b126f2ad9b2ab5b3900 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/allocator/simplereg.c - register allocator
 
-   Copyright (C) 1996-2005, 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, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   $Id: simplereg.c 7766 2007-04-19 13:24:48Z michi $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/method.hpp"
+#include "vm/options.h"
+#include "vm/resolve.hpp"
+#include "vm/string.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/show.h"
+#include "vm/jit/show.hpp"
 #include "vm/jit/allocator/simplereg.h"
 
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
 
 #if 0
 #    define LOG(args) printf args
@@ -66,6 +62,11 @@ static void simplereg_allocate_locals(jitdata *jd);
 static void simplereg_allocate_temporaries(jitdata *jd);
 
 
+/* size of a stackslot used by the internal ABI */
+
+#define SIZE_OF_STACKSLOT 8
+
+
 /* total number of registers */
 
 #if defined(HAS_ADDRESS_REGISTER_FILE)
@@ -201,45 +202,13 @@ static void simplereg_allocate_temporaries(jitdata *jd);
 
 #define NEW_MEM_SLOT(r)                                              \
     do {                                                             \
-        (r) = rd->memuse;                                            \
-        rd->memuse += memneeded + 1;                                 \
-    } while (0)
-
-#define NEW_MEM_SLOT_ALIGNED(r)                                      \
-    do {                                                             \
-        if ( (memneeded) && (rd->memuse & 1))                        \
-            rd->memuse++;                                            \
-        (r) = rd->memuse;                                            \
-        rd->memuse += memneeded + 1;                                 \
-    } while (0)
-
-#define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)                        \
-    do {                                                             \
-        if ( (memneeded) && (rd->memuse & 1)) {                      \
-                       PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse);      \
-            rd->memuse++;                                            \
-               }                                                            \
-        (r) = rd->memuse;                                            \
-        rd->memuse += memneeded + 1;                                 \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
+        rd->memuse += 1;                                             \
     } while (0)
 
-#if defined(ALIGN_LONGS_IN_MEMORY)
-#define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT_ALIGNED(r)
-#else
 #define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT(r)
-#endif
-
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
-#define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT_ALIGNED(r)
-#else
 #define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT(r)
-#endif
-
-#if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
-#define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
-#else
 #define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT(r)
-#endif
 
 
 /* macros for creating/freeing temporary variables ***************************/
@@ -277,9 +246,9 @@ static void simplereg_allocate_temporaries(jitdata *jd);
 /* regalloc ********************************************************************
 
    Does a simple register allocation.
-       
+
 *******************************************************************************/
-       
+
 bool regalloc(jitdata *jd)
 {
        /* There is a problem with the use of unused float argument
@@ -303,21 +272,21 @@ bool regalloc(jitdata *jd)
 /* simplereg_allocate_interfaces ***********************************************
 
    Allocates registers for all interface variables.
-       
+
 *******************************************************************************/
-       
+
 static void simplereg_allocate_interfaces(jitdata *jd)
 {
        methodinfo   *m;
+       codeinfo     *code;
        codegendata  *cd;
        registerdata *rd;
 
        int     s, t, tt, saved;
        int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
                        /* in case more vars are packed into this interface slot */
-       int             memneeded = 0;
-       /* Allocate LNG and DBL types first to ensure 2 memory slots or          */
-       /* registers on HAS_4BYTE_STACKSLOT architectures.                       */
+       /* Allocate LNG and DBL types first to ensure 2 registers                */
+       /* on some architectures.                                                */
        int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
        int     flags, regoff;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
@@ -326,22 +295,23 @@ static void simplereg_allocate_interfaces(jitdata *jd)
 
        /* get required compiler data */
 
-       m  = jd->m;
-       cd = jd->cd;
-       rd = jd->rd;
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
 
        /* rd->memuse was already set in stack.c to allocate stack space
           for passing arguments to called methods. */
 
 #if defined(__I386__)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+       if (checksync && code_is_synchronized(code)) {
                /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
                if (rd->memuse < 1)
                        rd->memuse = 1;
        }
 #endif
 
-       if (jd->isleafmethod) {
+       if (code_is_leafmethod(code)) {
                /* Reserve argument register, which will be used for Locals acting */
                /* as Parameters */
                if (rd->argintreguse < m->parseddesc->argintreguse)
@@ -381,14 +351,10 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                        intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
 
-#if defined(HAS_4BYTE_STACKSLOT)
-                       memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
-#endif
-
                        if (!saved) {
 #if defined(HAS_ADDRESS_REGISTER_FILE)
                                if (IS_ADR_TYPE(t)) {
-                                       if (!jd->isleafmethod && AVAIL_ARG_ADR) {
+                                       if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
                                                flags |= ARGREG;
                                                TAKE_ARG_ADR(regoff);
                                        } 
@@ -401,7 +367,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                        } 
                                        else {
                                                flags |= INMEMORY;
-                                               regoff = rd->memuse++;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }                                               
                                } 
                                else /* !IS_ADR_TYPE */
@@ -431,7 +397,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                fltalloc = s * 5 + t;
                                        }
                                        else { /* !IS_FLT_DBL_TYPE(t) */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                /*
                                                 * for i386 put all longs in memory
                                                 */
@@ -440,7 +406,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                        NEW_MEM_SLOT_INT_LNG(regoff);
                                                } 
                                                else
-#endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
+#endif
                                                        if (intalloc >= 0) {
                                                                /* Reuse memory slot(s)/register(s) for shared interface slots */
                                                                flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
@@ -483,7 +449,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                        }
                                        else {
                                                flags |= INMEMORY;
-                                               regoff = rd->memuse++;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }                                               
                                } 
                                else
@@ -506,7 +472,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                fltalloc = s * 5 + t;
                                        }
                                        else { /* IS_INT_LNG */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                /*
                                                 * for i386 put all longs in memory
                                                 */
@@ -554,9 +520,9 @@ static void simplereg_allocate_interfaces(jitdata *jd)
 /* simplereg_allocate_locals_leafmethod ****************************************
 
    Allocates registers for all local variables of a leafmethod.
-       
+
 *******************************************************************************/
-       
+
 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 {
        methodinfo   *m;
@@ -568,7 +534,6 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
        int     intalloc, fltalloc;
        varinfo *v;
        int     intregsneeded = 0;
-       int     memneeded = 0;
        int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
        int     fargcnt, iargcnt;
 #ifdef HAS_ADDRESS_REGISTER_FILE
@@ -601,9 +566,6 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                        intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
-#if defined(HAS_4BYTE_STACKSLOT)
-                       memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
-#endif
 
                        /*
                         *  The order of
@@ -645,7 +607,7 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                                }
                                else {
                                        v->flags |= INMEMORY;
-                                       v->vv.regoff = rd->memuse++;
+                                       v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                }                                               
                        } 
                        else {
@@ -685,7 +647,7 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 
                                } 
                                else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
@@ -762,18 +724,18 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 /* simplereg_allocate_locals ***************************************************
 
    Allocates registers for all local variables.
-       
+
 *******************************************************************************/
-       
+
 static void simplereg_allocate_locals(jitdata *jd)
 {
+       codeinfo     *code;
        codegendata  *cd;
        registerdata *rd;
 
        int     s, t, tt, varindex;
        int     intalloc, fltalloc;
        varinfo *v;
-       int     memneeded = 0;
        int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
        s4 intregsneeded;
@@ -781,10 +743,11 @@ static void simplereg_allocate_locals(jitdata *jd)
 
        /* get required compiler data */
 
-       cd = jd->cd;
-       rd = jd->rd;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
 
-       if (jd->isleafmethod) {
+       if (code_is_leafmethod(code)) {
                simplereg_allocate_locals_leafmethod(jd);
                return;
        }
@@ -804,10 +767,6 @@ static void simplereg_allocate_locals(jitdata *jd)
                                intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
 
-#if defined(HAS_4BYTE_STACKSLOT)
-                               memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
-#endif
-
 #ifdef HAS_ADDRESS_REGISTER_FILE
                                if (IS_ADR_TYPE(t)) {
                                        if (AVAIL_SAV_ADR) {
@@ -816,7 +775,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                        }
                                        else {
                                                v->flags = INMEMORY;
-                                               v->vv.regoff = rd->memuse++;
+                                               v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }
                                } 
                                else {
@@ -837,7 +796,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                        fltalloc = jd->local_map[s * 5 + t];
                                }
                                else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
@@ -866,7 +825,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                                        v->flags = INMEMORY;
                                                        NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
                                                }
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        }
 #endif
                                        intalloc = jd->local_map[s * 5 + t];
@@ -884,9 +843,6 @@ static void simplereg_init(jitdata *jd, registerdata *rd)
        int i;
 
        rd->freememtop = 0;
-#if defined(HAS_4BYTE_STACKSLOT)
-       rd->freememtop_2 = 0;
-#endif
 
        rd->freetmpinttop = 0;
        rd->freesavinttop = 0;
@@ -1001,7 +957,6 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
        s4 intregsneeded;
 #endif
-       s4 memneeded;
        s4 tryagain;
        registerdata *rd;
        varinfo      *v;
@@ -1021,12 +976,6 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
        intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
 #endif
 
-#if defined(HAS_4BYTE_STACKSLOT)
-       memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
-#else
-       memneeded = 0;
-#endif
-
        for(; tryagain; --tryagain) {
                if (tryagain == 1) {
                        if (!(v->flags & SAVEDVAR))
@@ -1056,7 +1005,7 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
                                        }
                                } 
                                else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
@@ -1112,7 +1061,7 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
 
                                } 
                                else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
@@ -1147,15 +1096,10 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
 
        v->flags |= INMEMORY;
 
-#if defined(HAS_4BYTE_STACKSLOT)
-       if ((memneeded == 1) && (rd->freememtop_2 > 0))
-               POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
+       if (rd->freememtop > 0)
+               POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
        else
-#endif /*defined(HAS_4BYTE_STACKSLOT) */
-               if ((memneeded == 0) && (rd->freememtop > 0))
-                       POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
-               else
-                       NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
+               NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
 }
 
 
@@ -1167,14 +1111,16 @@ static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
 
        /* if this is a copy of another variable, just decrement the copy counter */
 
-       /* XXX split reg/mem variables on arm may need special handling here */
-
        if (flags & INMEMORY) {
+               int32_t memindex;
+
                if (flags & INOUT)
                        return;
 
-               if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
-                       rd->memcopycount[regoff]--;
+               memindex = regoff / SIZE_OF_STACKSLOT;
+
+               if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
+                       rd->memcopycount[memindex]--;
                        return;
                }
        }
@@ -1201,13 +1147,7 @@ static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
        }
 
        if (flags & INMEMORY) {
-#if defined(HAS_4BYTE_STACKSLOT)
-               if (IS_2_WORD_TYPE(type))
-                       PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
-               else 
-#endif
-                       PUSH_BACK(rd->freemem, rd->freememtop, regoff);
-
+               PUSH_BACK(rd->freemem, rd->freememtop, regoff);
                return;
        } 
 
@@ -1336,7 +1276,7 @@ static void simplereg_allocate_temporaries(jitdata *jd)
 
                        /* assert that all copy counts are zero */
 
-#if !defined(NDEBUG)
+#if !defined(NDEBUG) && !defined(ENABLE_SSA)
                        for (i=0; i < TOTAL_REG_CNT; ++i)
                                assert(rd->regcopycount[i] == 0);
 #endif
@@ -1432,6 +1372,7 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                case ICMD_FCONST:
                                case ICMD_DCONST:
                                case ICMD_ACONST:
+                               case ICMD_GETEXCEPTION:
 
                                        /* pop 0 push 1 load */
                                        
@@ -1543,32 +1484,6 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                case ICMD_IF_LCMPGT:
                                case ICMD_IF_LCMPLE:
 
-                               case ICMD_IF_FCMPEQ:
-                               case ICMD_IF_FCMPNE:
-
-                               case ICMD_IF_FCMPL_LT:
-                               case ICMD_IF_FCMPL_GE:
-                               case ICMD_IF_FCMPL_GT:
-                               case ICMD_IF_FCMPL_LE:
-
-                               case ICMD_IF_FCMPG_LT:
-                               case ICMD_IF_FCMPG_GE:
-                               case ICMD_IF_FCMPG_GT:
-                               case ICMD_IF_FCMPG_LE:
-
-                               case ICMD_IF_DCMPEQ:
-                               case ICMD_IF_DCMPNE:
-
-                               case ICMD_IF_DCMPL_LT:
-                               case ICMD_IF_DCMPL_GE:
-                               case ICMD_IF_DCMPL_GT:
-                               case ICMD_IF_DCMPL_LE:
-
-                               case ICMD_IF_DCMPG_LT:
-                               case ICMD_IF_DCMPG_GE:
-                               case ICMD_IF_DCMPG_GT:
-                               case ICMD_IF_DCMPG_LE:
-
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:
 
@@ -1601,14 +1516,15 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                                v = VAROP(iptr->dst);
 
                                                if (v->flags & INMEMORY) {
-                                                       if (v->vv.regoff >= rd->memcopycountsize) {
-                                                               int newsize = (v->vv.regoff + 1) * 2;
+                                                       int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
+                                                       if (memindex >= rd->memcopycountsize) {
+                                                               int newsize = (memindex + 1) * 2;
                                                                i = rd->memcopycountsize;
                                                                rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
                                                                MZERO(rd->memcopycount + i, int, newsize - i);
                                                                rd->memcopycountsize = newsize;
                                                        }
-                                                       rd->memcopycount[v->vv.regoff]++;
+                                                       rd->memcopycount[memindex]++;
                                                }
                                                else {
                                                        /* XXX split reg/mem variables on arm may need special handling here */
@@ -1812,8 +1728,8 @@ void simplereg_make_statistics(jitdata *jd)
        int i;
        s4 len;
 #if 0
-       stackptr    src, src_old;
-       stackptr    dst;
+       stackelement_t*    src, src_old;
+       stackelement_t*    dst;
        instruction *iptr;
 #endif
        basicblock  *bptr;