2001-09-23 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Sun, 23 Sep 2001 07:57:26 +0000 (07:57 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Sun, 23 Sep 2001 07:57:26 +0000 (07:57 -0000)
* testjit.c: use the memory pool to avoid memory leaks

monoburg.c: add a macro MBALLOC_STATE to define the allocation
function for MBState. Added an additional user data argument to
mono_burg_label - the data can be used in the cost functions. The
type can be defined with MBCOST_DATA macro.
(emit_cost_func): inline cost functions

svn path=/trunk/mono/; revision=928

mono/jit/ChangeLog
mono/jit/Makefile.am
mono/jit/jit.c
mono/jit/jit.h
mono/jit/mempool.c [new file with mode: 0644]
mono/jit/testjit.c
mono/jit/x86.brg
mono/metadata/mempool.c [new file with mode: 0644]
mono/monoburg/ChangeLog
mono/monoburg/monoburg.c
mono/monoburg/sample.brg

index 5c647ae6ddf610c71171921c6f0098fdded2a34f..53907e71408ec186c3170d68943d9c3fae682401 100644 (file)
@@ -1,3 +1,11 @@
+2001-09-23  Dietmar Maurer  <dietmar@ximian.com>
+
+       * testjit.c: use the memory pool to avoid memory leaks
+
+2001-09-22  Dietmar Maurer  <dietmar@ximian.com>
+
+       * x86.brg: increment the stack pointer after function calls
+
 2001-09-21  Dick Porter  <dick@ximian.com>
 
        * Makefile.am (testjit_LDADD): Added PTHREAD_LIBS to the link line
index e446b8d21b715764c21d1878f99847992184c962..d3bf6f19155afdefbe5dae14bec6f2215dba1185 100644 (file)
@@ -12,6 +12,7 @@ testjit_SOURCES =             \
        jit.h                   \
        regset.h                \
        regset.c                \
+       mempool.c               \
        testjit.h               \
        testjit.c
 
index 22e6c8fd5ff44c0f56209ade0b9525b56c477326..0a5af3e608998dfc1877b1731ad4ce8ed76b44ac 100644 (file)
@@ -18,6 +18,7 @@
 #include "jit.h"
 #include "testjit.h"
 #include "regset.h"
+
 /*
  * Pull the list of opcodes
  */
@@ -38,12 +39,11 @@ char *opcode_names [] = {
 
 #define MAKE_CJUMP(name)                                                      \
 case CEE_##name:                                                              \
-case CEE_##name##_S:                                                          \
-{                                                                             \
+case CEE_##name##_S: {                                                        \
        int near_jump = *ip == CEE_##name##_S;                                \
        ++ip;                                                                 \
        sp -= 2;                                                              \
-       t1 = ctree_new (MB_TERM_##name, 0, sp [0], sp [1]);                   \
+       t1 = ctree_new (mp, MB_TERM_##name, 0, sp [0], sp [1]);               \
        if (near_jump)                                                        \
                t1->data.i = cli_addr + 2 + (signed char) *ip;                \
        else                                                                  \
@@ -54,7 +54,16 @@ case CEE_##name##_S:                                                          \
        break;                                                                \
 }
 
-
+#define MAKE_BI_ALU(name)                                                     \
+case CEE_##name: {                                                            \
+       ++ip;                                                                 \
+       sp -= 2;                                                              \
+       t1 = ctree_new (mp, MB_TERM_##name, 0, sp [0], sp [1]);               \
+       t1->cli_addr = sp [0]->cli_addr;                                      \
+       PUSH_TREE (t1);                                                       \
+       break;                                                                \
+}
+       
 /* Whether to dump the assembly code after genreating it */
 gboolean dump_asm    = FALSE;
 
@@ -63,6 +72,17 @@ gboolean dump_forest = FALSE;
 
 static gpointer mono_compile_method (MonoMethod *method);
 
+/* 
+ * allocates static data (we never free it). Such data is
+ * needed by the code generation to store constants. We should
+ * use something faster than g_malloc()
+ */
+inline static gpointer
+alloc_static (int size)
+{
+       return g_malloc (size);
+}
+
 static MonoRegSet *
 get_x86_regset ()
 {
@@ -232,9 +252,10 @@ compute_branches (MBCodeGenStatus *s)
 }
 
 static MBTree *
-ctree_new (int op, MonoTypeEnum type, MBTree *left, MBTree *right)
+ctree_new (MonoMemPool *mp, int op, MonoTypeEnum type, 
+          MBTree *left, MBTree *right)
 {
-       MBTree *t = g_malloc (sizeof (MBTree));
+       MBTree *t = mono_mempool_alloc0 (mp, sizeof (MBTree));
 
        t->op = op;
        t->left = left;
@@ -242,21 +263,14 @@ ctree_new (int op, MonoTypeEnum type, MBTree *left, MBTree *right)
        t->type = type;
        t->reg1 = -1;
        t->reg2 = -1;
-       t->is_jump = 0;
-       t->jump_target = 0;
-       t->last_instr = 0;
-       t->exclude_edx = 0;
        t->cli_addr = -1;
-       t->addr = 0;
-       t->first_addr = 0;
-       t->emit = NULL;
        return t;
 }
 
 static MBTree *
-ctree_new_leaf (int op, MonoTypeEnum type)
+ctree_new_leaf (MonoMemPool *mp, int op, MonoTypeEnum type)
 {
-       return ctree_new (op, type, NULL, NULL);
+       return ctree_new (mp, op, type, NULL, NULL);
 }
 
 static void
@@ -303,17 +317,18 @@ print_forest (GPtrArray *forest)
 }
 
 static void
-forest_label (GPtrArray *forest)
+forest_label (MBCodeGenStatus *s)
 {
+       GPtrArray *forest = s->forest;
        const int top = forest->len;
        int i;
        
        for (i = 0; i < top; i++) {
                MBTree *t1 = (MBTree *) g_ptr_array_index (forest, i);
-               MBState *s;
+               MBState *mbstate;
 
-               s =  mono_burg_label (t1);
-               if (!s) {
+               mbstate =  mono_burg_label (t1, s);
+               if (!mbstate) {
                        g_warning ("tree does not match");
                        print_tree (t1); printf ("\n");
                        g_assert_not_reached ();
@@ -373,7 +388,7 @@ emit_method (MonoMethod *method, MBCodeGenStatus *s)
 {
        method->addr = s->start = s->code = g_malloc (1024);
 
-       forest_label (s->forest);
+       forest_label (s);
 
        forest_allocate_regs (s);
        arch_emit_prologue (s);
@@ -443,6 +458,7 @@ mono_compile_method (MonoMethod *method)
        MonoMethodHeader *header;
        MonoMethodSignature *signature;
        MonoImage *image;
+       MonoMemPool *mp;
        MBTree **sp, **stack, *t1, *t2;
        register const unsigned char *ip, *end;
        guint *locals_offsets;
@@ -462,6 +478,8 @@ mono_compile_method (MonoMethod *method)
        ip = header->code;
        end = ip + header->code_size;
 
+       cgstat.mp = mp = mono_mempool_new ();
+
        sp = stack = alloca (sizeof (MBTree *) * header->max_stack);
        
        if (header->num_locals) {
@@ -506,22 +524,42 @@ mono_compile_method (MonoMethod *method)
                guint32 cli_addr = ip - header->code;
                switch (*ip) {
 
-               case CEE_NOP: 
+               case CEE_NOP: 
                        ++ip;
                        break;
-
-               case CEE_BREAK: 
+               }
+               case CEE_BREAK: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BREAK, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BREAK, 0);
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        break;
-
+               }
+/*
+               case CEE_SWITCH:
+                       guint32 n;
+                       const unsigned char *st;
+                       ++ip;
+                       n = read32 (ip);
+                       ip += 4;
+                       st = ip + 4 * n;
+                       --sp;
+                       if ((guint32)sp->data.i < n) {
+                               gint offset;
+                               ip += 4 * (guint32)sp->data.i;
+                               offset = read32 (ip);
+                               ip = st + offset;
+                       } else {
+                               ip = st;
+                       }
+                       break;
+               }
+*/
                case CEE_CALL: {
                        MonoMethodSignature *csig;
                        MonoMethod *cm;
                        guint32 token, nargs;
-                       int i;
+                       int i, align, size, offset = 0;
                        gint32 fa;
 
                        ++ip;
@@ -536,29 +574,31 @@ mono_compile_method (MonoMethod *method)
 
                                fa = sp [-nargs]->cli_addr;
 
-                               for (i = 0; i < nargs; i++) {
+                               for (i = nargs - 1; i >= 0; i--) {
                                        sp--;
-                                       t1 = ctree_new (MB_TERM_ARG, 0, *sp, NULL);
-                               
-                                       if (i)
-                                               t1->cli_addr = -1;
-                                       else
-                                               t1->cli_addr = fa;
-                                       
+                                       t1 = ctree_new (mp, MB_TERM_ARG, 0, *sp, NULL); 
                                        ADD_TREE (t1);
+                                       if (!i && csig->hasthis)
+                                               size = mono_type_size (&cm->klass->this_arg, &align);
+                                       else
+                                               size = mono_type_size (cm->signature->params [i], &align);
+
+                                       // fixme: does this really work ?
+                                       offset += (size + 3) & ~3;
                                }
 
+                               t1->cli_addr = fa;
                                fa = -1;
                        } else
                                fa = cli_addr;
-                       
+
                        cm->addr = create_jit_trampoline (cm);
                        
                        if (csig->ret->type != MONO_TYPE_VOID) {
-                               int size, align;
-                               t1 = ctree_new_leaf (MB_TERM_CALL, csig->ret->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_CALL, csig->ret->type);
                                t1->data.p = cm;
-                               t2 = ctree_new (MB_TERM_STLOC, csig->ret->type, t1, NULL);
+                               t1->size = offset;
+                               t2 = ctree_new (mp, MB_TERM_STLOC, csig->ret->type, t1, NULL);
                                size = mono_type_size (csig->ret, &align);
                                local_offset += align - 1;
                                local_offset &= ~(align - 1);
@@ -566,35 +606,36 @@ mono_compile_method (MonoMethod *method)
                                t2->data.i = - local_offset;
                                t2->cli_addr = fa;
                                ADD_TREE (t2);
-                               t1 = ctree_new_leaf (MB_TERM_LDLOC, t2->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, t2->type);
                                t1->data.i = t2->data.i;
                                PUSH_TREE (t1);
                        } else {
-                               t1 = ctree_new_leaf (MB_TERM_CALL, MONO_TYPE_VOID);
+                               t1 = ctree_new_leaf (mp, MB_TERM_CALL, MONO_TYPE_VOID);
                                t1->data.p = cm;
+                               t1->size = offset;
                                t1->cli_addr = fa;
                                ADD_TREE (t1);
                        }
                        break;
                }
-               case CEE_LDC_I4_S: 
+               case CEE_LDC_I4_S: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = *ip;
                        ++ip;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
-               case CEE_LDC_I4: 
+               }
+               case CEE_LDC_I4: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = read32 (ip);
                        ip += 4;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
+               }
                case CEE_LDC_I4_M1:
                case CEE_LDC_I4_0:
                case CEE_LDC_I4_1:
@@ -604,23 +645,54 @@ mono_compile_method (MonoMethod *method)
                case CEE_LDC_I4_5:
                case CEE_LDC_I4_6:
                case CEE_LDC_I4_7:
-               case CEE_LDC_I4_8:
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+               case CEE_LDC_I4_8: {
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = (*ip) - CEE_LDC_I4_0;
                        ++ip;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
-               case CEE_LDC_R8: 
+               }
+               case CEE_LDNULL: {
+                       //fixme: don't know if this is portable ?
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_R8, MONO_TYPE_R8);
-                       (const void *) t1->data.p = ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1->data.i = 0;
                        t1->cli_addr = cli_addr;
+                       PUSH_TREE (t1);
+                       break;
+               }
+               case CEE_LDC_I8: {
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I8, MONO_TYPE_I8);
+                       t1->data.l =  read64 (ip);
                        ip += 8;
+                       t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);         
                        break;
-
+               }
+               case CEE_LDC_R4: {
+                       float *f = alloc_static (sizeof (float));
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_R4, MONO_TYPE_R4);
+                       readr4 (ip, f);
+                       t1->data.p = f;
+                       t1->cli_addr = cli_addr;
+                       ip += 4;
+                       PUSH_TREE (t1);         
+                       break;
+               }
+               case CEE_LDC_R8: { 
+                       double *d = alloc_static (sizeof (double));
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_R8, MONO_TYPE_R8);
+                       readr8 (ip, d);
+                       t1->data.p = d;
+                       t1->cli_addr = cli_addr;
+                       ip += 8;
+                       PUSH_TREE (t1);         
+                       break;
+               }
                case CEE_LDLOC_0:
                case CEE_LDLOC_1:
                case CEE_LDLOC_2:
@@ -628,7 +700,7 @@ mono_compile_method (MonoMethod *method)
                        int n = (*ip) - CEE_LDLOC_0;
                        ++ip;
 
-                       t1 = ctree_new_leaf (MB_TERM_LDLOC, LOCAL_TYPE (n)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, LOCAL_TYPE (n)->type);
                        t1->data.i = LOCAL_POS (n);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
@@ -637,7 +709,7 @@ mono_compile_method (MonoMethod *method)
                case CEE_LDLOC_S: {
                        ++ip;
 
-                       t1 = ctree_new_leaf (MB_TERM_LDLOC, LOCAL_TYPE (*ip)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, LOCAL_TYPE (*ip)->type);
                        t1->data.i = LOCAL_POS (*ip);
                        t1->cli_addr = cli_addr;
                        ++ip;
@@ -645,7 +717,6 @@ mono_compile_method (MonoMethod *method)
                        PUSH_TREE (t1);
                        break;
                }
-
                case CEE_STLOC_0:
                case CEE_STLOC_1:
                case CEE_STLOC_2:
@@ -654,7 +725,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_STLOC, LOCAL_TYPE (n)->type, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_STLOC, LOCAL_TYPE (n)->type, *sp, NULL);
                        t1->data.i = LOCAL_POS (n);
                        t1->cli_addr = sp [0]->cli_addr;
                        ADD_TREE (t1);                  
@@ -664,7 +735,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_STLOC, LOCAL_TYPE (*ip)->type, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_STLOC, LOCAL_TYPE (*ip)->type, *sp, NULL);
                        t1->data.i = LOCAL_POS (*ip);
                        t1->cli_addr = sp [0]->cli_addr;
                        ++ip;
@@ -672,55 +743,39 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);                  
                        break;
                }
-               case CEE_ADD:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_ADD, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_SUB:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_SUB, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
 
-               case CEE_MUL:
+               MAKE_BI_ALU (ADD)
+               MAKE_BI_ALU (SUB)
+               MAKE_BI_ALU (AND)
+               MAKE_BI_ALU (OR)
+               MAKE_BI_ALU (XOR)
+                       //MAKE_BI_ALU (SHL)
+                       //MAKE_BI_ALU (SHR)
+                       //MAKE_BI_ALU (SHR_UN)
+               MAKE_BI_ALU (MUL)
+               MAKE_BI_ALU (DIV)
+                       //MAKE_BI_ALU (DIV_UN)
+                       //MAKE_BI_ALU (REM)
+                       //MAKE_BI_ALU (REM_UN)
+
+               case CEE_BR_S: {
                        ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_MUL, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_DIV:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_DIV, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_BR_S: 
-                       ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BR, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BR, 0);
                        t1->data.i = cli_addr + 2 + (signed char) *ip;
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        ++ip;
                        break;
-
-               case CEE_BR:
+               }
+               case CEE_BR: {
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BR, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BR, 0);
                        t1->data.i = cli_addr + 5 + (gint32) read32(ip);
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        ip += 4;
                        break;
+               }
 
                MAKE_CJUMP(BGT)
                MAKE_CJUMP(BGT_UN)
@@ -739,7 +794,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_BRTRUE, 0, sp [0], NULL);
+                       t1 = ctree_new (mp, MB_TERM_BRTRUE, 0, sp [0], NULL);
 
                        if (near_jump)
                                t1->data.i = cli_addr + 2 + (signed char) *ip;
@@ -751,14 +806,13 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);
                        break;
                }
-
                case CEE_BRFALSE:
                case CEE_BRFALSE_S: {
                        int near_jump = *ip == CEE_BRFALSE_S;
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_BRFALSE, 0, sp [0], NULL);
+                       t1 = ctree_new (mp, MB_TERM_BRFALSE, 0, sp [0], NULL);
 
                        if (near_jump)
                                t1->data.i = cli_addr + 2 + (signed char) *ip;
@@ -770,15 +824,15 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);
                        break;
                }
-               case CEE_RET:
+               case CEE_RET: {
                        ip++;
 
                        if (signature->ret->type != MONO_TYPE_VOID) {
                                --sp;
-                               t1 = ctree_new (MB_TERM_RETV, 0, *sp, NULL);
+                               t1 = ctree_new (mp, MB_TERM_RETV, 0, *sp, NULL);
                                t1->cli_addr = sp [0]->cli_addr;
                        } else {
-                               t1 = ctree_new (MB_TERM_RET, 0, NULL, NULL);
+                               t1 = ctree_new (mp, MB_TERM_RET, 0, NULL, NULL);
                                t1->cli_addr = cli_addr;
                        }
 
@@ -791,86 +845,85 @@ mono_compile_method (MonoMethod *method)
                                g_warning ("more values on stack: %d", sp - stack);
 
                        break;
-
+               }
                case CEE_LDARG_0:
                case CEE_LDARG_1:
                case CEE_LDARG_2:
                case CEE_LDARG_3: {
                        int n = (*ip) - CEE_LDARG_0;
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (n)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (n)->type);
                        t1->data.i = ARG_POS (n);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
                }
-
-               case CEE_LDARG_S:
+               case CEE_LDARG_S: {
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (*ip)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (*ip)->type);
                        t1->data.i = ARG_POS (*ip);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        ++ip;
                        break;
-
-               case CEE_DUP: 
+               }
+               case CEE_DUP: {
                        ++ip; 
 
                        if (sp [-1]->op == MB_TERM_LDLOC) {
-                               t1 = ctree_new (0, 0, NULL, NULL);
+                               t1 = ctree_new (mp, 0, 0, NULL, NULL);
                                *t1 = *sp [-1];
                                PUSH_TREE (t1);         
                        } else 
                                g_assert_not_reached ();
 
                        break;
-
-               case CEE_POP:
+               }
+               case CEE_POP: {
                        ++ip;
                        --sp;
                        /*
                         * all side effects are already on the forest,
                         * so we can simply ignore this tree
                         */
-                       g_free (*sp);
+                       // we use the mompool g_free (*sp);
                        break;
-
+               }
                case CEE_CONV_U1: 
-               case CEE_CONV_I1: 
+               case CEE_CONV_I1: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I1, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I1, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case CEE_CONV_U2: 
-               case CEE_CONV_I2: 
+               case CEE_CONV_I2: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I2, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I2, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case CEE_CONV_I: 
-               case CEE_CONV_I4:
+               case CEE_CONV_I4: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I4, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I4, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
-               case CEE_CONV_I8:
+               }
+               case CEE_CONV_I8: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I8, MONO_TYPE_I8, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I8, MONO_TYPE_I8, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case 0xFE:
                        ++ip;                   
                        switch (*ip) {
@@ -879,7 +932,7 @@ mono_compile_method (MonoMethod *method)
                                ++ip;
                                n = read32 (ip);
                                ip += 4;
-                               t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (n)->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (n)->type);
                                t1->data.i = ARG_POS (n);
                                t1->cli_addr = cli_addr;
                                PUSH_TREE (t1);
@@ -906,6 +959,8 @@ mono_compile_method (MonoMethod *method)
        emit_method (method, &cgstat);
 
        mono_regset_free (cgstat.rs);
+       g_ptr_array_free (forest, TRUE);
+       mono_mempool_destroy (cgstat.mp);
 
        return method->addr;
 }
index 7c6711340da906a796ca5e6ecdc2548ac4b0f87f..5c7e0d47189bf30601d6df334821c4a90ad2820b 100644 (file)
@@ -1,9 +1,36 @@
 #ifndef _MONO_JIT_JIT_H_
 #define _MONO_JIT_JIT_H_
 
-#include "codegen.h"
+#include "regset.h"
 
-void arch_emit_prologue (MBCodeGenStatus *s);
-void arch_emit_epilogue (MBCodeGenStatus *s);
+typedef struct _MonoMemPool MonoMemPool;
+
+typedef struct {
+       MonoMemPool *mp;
+       guint8 *start;
+       guint8 *code;
+       gint32 locals_size;
+       GPtrArray *forest;
+       MonoRegSet *rs;
+       guint32 epilog;
+} MBCodeGenStatus;
+
+MonoMemPool *
+mono_mempool_new      (void);
+
+void
+mono_mempool_destroy  (MonoMemPool *pool);
+
+gpointer
+mono_mempool_alloc    (MonoMemPool *pool, guint size);
+
+gpointer
+mono_mempool_alloc0   (MonoMemPool *pool, guint size);
+
+void 
+arch_emit_prologue    (MBCodeGenStatus *s);
+
+void 
+arch_emit_epilogue    (MBCodeGenStatus *s);
 
 #endif
diff --git a/mono/jit/mempool.c b/mono/jit/mempool.c
new file mode 100644 (file)
index 0000000..2fa2bd2
--- /dev/null
@@ -0,0 +1,107 @@
+#include <config.h>
+#include <glib.h>
+
+#include "jit.h"
+
+/*
+ * MonoMemPool is for fast allocation of memory. We free
+ * all memory when the pool is destroyed.
+ */
+
+#if SIZEOF_VOID_P > SIZEOF_LONG
+#define MEM_ALIGN     SIZEOF_VOID_P
+#else
+#define MEM_ALIGN     SIZEOF_LONG
+#endif
+
+#define MONO_MEMPOOL_PAGESIZE 8192
+
+struct _MonoMemPool {
+       MonoMemPool *next;
+       gint rest;
+       gpointer pos;
+};
+
+/**
+ * mono_mempool_new:
+ *
+ * Returns: a new memory pool.
+ */
+MonoMemPool *
+mono_mempool_new ()
+{
+
+       MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
+       pool->next = NULL;
+       pool->pos = (gpointer)pool + sizeof (MonoMemPool);
+       pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+       return pool;
+}
+
+/**
+ * mono_mempool_destroy:
+ * @pool: the momory pool to destroy
+ *
+ * Free all memory associated with this pool.
+ */
+void
+mono_mempool_destroy (MonoMemPool *pool)
+{
+       MonoMemPool *p, *n;
+
+       p = pool;
+       while (p) {
+               n = p->next;
+               g_free (p);
+               p = n;
+       }
+}
+
+/**
+ * mono_mempool_alloc:
+ * @pool: the momory pool to destroy
+ * @size: size of the momory block
+ *
+ * Allocates a new block of memory in @pool. @size must 
+ * be smaller than 256.
+ *
+ * Returns: the address of a newly allocated memory block.
+ */
+gpointer
+mono_mempool_alloc (MonoMemPool *pool, guint size)
+{
+       gpointer rval;
+
+       g_assert (pool != NULL);
+       g_assert (size < 256);
+
+       size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
+
+       if (pool->rest < size) {
+               MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
+               np->next = pool->next;
+               pool->next = np;
+               pool->pos = (gpointer)np + sizeof (MonoMemPool);
+               pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+       }
+
+       rval = pool->pos;
+       pool->rest -= size;
+       pool->pos += size;
+
+       return rval;
+}
+
+/**
+ * mono_mempool_alloc0:
+ *
+ * same as mono_mempool_alloc, but fills memory with zero.
+ */
+gpointer
+mono_mempool_alloc0 (MonoMemPool *pool, guint size)
+{
+       gpointer rval = mono_mempool_alloc (pool, size);
+       memset (rval, 0, size);
+       return rval;
+}
+
index 22e6c8fd5ff44c0f56209ade0b9525b56c477326..0a5af3e608998dfc1877b1731ad4ce8ed76b44ac 100644 (file)
@@ -18,6 +18,7 @@
 #include "jit.h"
 #include "testjit.h"
 #include "regset.h"
+
 /*
  * Pull the list of opcodes
  */
@@ -38,12 +39,11 @@ char *opcode_names [] = {
 
 #define MAKE_CJUMP(name)                                                      \
 case CEE_##name:                                                              \
-case CEE_##name##_S:                                                          \
-{                                                                             \
+case CEE_##name##_S: {                                                        \
        int near_jump = *ip == CEE_##name##_S;                                \
        ++ip;                                                                 \
        sp -= 2;                                                              \
-       t1 = ctree_new (MB_TERM_##name, 0, sp [0], sp [1]);                   \
+       t1 = ctree_new (mp, MB_TERM_##name, 0, sp [0], sp [1]);               \
        if (near_jump)                                                        \
                t1->data.i = cli_addr + 2 + (signed char) *ip;                \
        else                                                                  \
@@ -54,7 +54,16 @@ case CEE_##name##_S:                                                          \
        break;                                                                \
 }
 
-
+#define MAKE_BI_ALU(name)                                                     \
+case CEE_##name: {                                                            \
+       ++ip;                                                                 \
+       sp -= 2;                                                              \
+       t1 = ctree_new (mp, MB_TERM_##name, 0, sp [0], sp [1]);               \
+       t1->cli_addr = sp [0]->cli_addr;                                      \
+       PUSH_TREE (t1);                                                       \
+       break;                                                                \
+}
+       
 /* Whether to dump the assembly code after genreating it */
 gboolean dump_asm    = FALSE;
 
@@ -63,6 +72,17 @@ gboolean dump_forest = FALSE;
 
 static gpointer mono_compile_method (MonoMethod *method);
 
+/* 
+ * allocates static data (we never free it). Such data is
+ * needed by the code generation to store constants. We should
+ * use something faster than g_malloc()
+ */
+inline static gpointer
+alloc_static (int size)
+{
+       return g_malloc (size);
+}
+
 static MonoRegSet *
 get_x86_regset ()
 {
@@ -232,9 +252,10 @@ compute_branches (MBCodeGenStatus *s)
 }
 
 static MBTree *
-ctree_new (int op, MonoTypeEnum type, MBTree *left, MBTree *right)
+ctree_new (MonoMemPool *mp, int op, MonoTypeEnum type, 
+          MBTree *left, MBTree *right)
 {
-       MBTree *t = g_malloc (sizeof (MBTree));
+       MBTree *t = mono_mempool_alloc0 (mp, sizeof (MBTree));
 
        t->op = op;
        t->left = left;
@@ -242,21 +263,14 @@ ctree_new (int op, MonoTypeEnum type, MBTree *left, MBTree *right)
        t->type = type;
        t->reg1 = -1;
        t->reg2 = -1;
-       t->is_jump = 0;
-       t->jump_target = 0;
-       t->last_instr = 0;
-       t->exclude_edx = 0;
        t->cli_addr = -1;
-       t->addr = 0;
-       t->first_addr = 0;
-       t->emit = NULL;
        return t;
 }
 
 static MBTree *
-ctree_new_leaf (int op, MonoTypeEnum type)
+ctree_new_leaf (MonoMemPool *mp, int op, MonoTypeEnum type)
 {
-       return ctree_new (op, type, NULL, NULL);
+       return ctree_new (mp, op, type, NULL, NULL);
 }
 
 static void
@@ -303,17 +317,18 @@ print_forest (GPtrArray *forest)
 }
 
 static void
-forest_label (GPtrArray *forest)
+forest_label (MBCodeGenStatus *s)
 {
+       GPtrArray *forest = s->forest;
        const int top = forest->len;
        int i;
        
        for (i = 0; i < top; i++) {
                MBTree *t1 = (MBTree *) g_ptr_array_index (forest, i);
-               MBState *s;
+               MBState *mbstate;
 
-               s =  mono_burg_label (t1);
-               if (!s) {
+               mbstate =  mono_burg_label (t1, s);
+               if (!mbstate) {
                        g_warning ("tree does not match");
                        print_tree (t1); printf ("\n");
                        g_assert_not_reached ();
@@ -373,7 +388,7 @@ emit_method (MonoMethod *method, MBCodeGenStatus *s)
 {
        method->addr = s->start = s->code = g_malloc (1024);
 
-       forest_label (s->forest);
+       forest_label (s);
 
        forest_allocate_regs (s);
        arch_emit_prologue (s);
@@ -443,6 +458,7 @@ mono_compile_method (MonoMethod *method)
        MonoMethodHeader *header;
        MonoMethodSignature *signature;
        MonoImage *image;
+       MonoMemPool *mp;
        MBTree **sp, **stack, *t1, *t2;
        register const unsigned char *ip, *end;
        guint *locals_offsets;
@@ -462,6 +478,8 @@ mono_compile_method (MonoMethod *method)
        ip = header->code;
        end = ip + header->code_size;
 
+       cgstat.mp = mp = mono_mempool_new ();
+
        sp = stack = alloca (sizeof (MBTree *) * header->max_stack);
        
        if (header->num_locals) {
@@ -506,22 +524,42 @@ mono_compile_method (MonoMethod *method)
                guint32 cli_addr = ip - header->code;
                switch (*ip) {
 
-               case CEE_NOP: 
+               case CEE_NOP: 
                        ++ip;
                        break;
-
-               case CEE_BREAK: 
+               }
+               case CEE_BREAK: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BREAK, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BREAK, 0);
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        break;
-
+               }
+/*
+               case CEE_SWITCH:
+                       guint32 n;
+                       const unsigned char *st;
+                       ++ip;
+                       n = read32 (ip);
+                       ip += 4;
+                       st = ip + 4 * n;
+                       --sp;
+                       if ((guint32)sp->data.i < n) {
+                               gint offset;
+                               ip += 4 * (guint32)sp->data.i;
+                               offset = read32 (ip);
+                               ip = st + offset;
+                       } else {
+                               ip = st;
+                       }
+                       break;
+               }
+*/
                case CEE_CALL: {
                        MonoMethodSignature *csig;
                        MonoMethod *cm;
                        guint32 token, nargs;
-                       int i;
+                       int i, align, size, offset = 0;
                        gint32 fa;
 
                        ++ip;
@@ -536,29 +574,31 @@ mono_compile_method (MonoMethod *method)
 
                                fa = sp [-nargs]->cli_addr;
 
-                               for (i = 0; i < nargs; i++) {
+                               for (i = nargs - 1; i >= 0; i--) {
                                        sp--;
-                                       t1 = ctree_new (MB_TERM_ARG, 0, *sp, NULL);
-                               
-                                       if (i)
-                                               t1->cli_addr = -1;
-                                       else
-                                               t1->cli_addr = fa;
-                                       
+                                       t1 = ctree_new (mp, MB_TERM_ARG, 0, *sp, NULL); 
                                        ADD_TREE (t1);
+                                       if (!i && csig->hasthis)
+                                               size = mono_type_size (&cm->klass->this_arg, &align);
+                                       else
+                                               size = mono_type_size (cm->signature->params [i], &align);
+
+                                       // fixme: does this really work ?
+                                       offset += (size + 3) & ~3;
                                }
 
+                               t1->cli_addr = fa;
                                fa = -1;
                        } else
                                fa = cli_addr;
-                       
+
                        cm->addr = create_jit_trampoline (cm);
                        
                        if (csig->ret->type != MONO_TYPE_VOID) {
-                               int size, align;
-                               t1 = ctree_new_leaf (MB_TERM_CALL, csig->ret->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_CALL, csig->ret->type);
                                t1->data.p = cm;
-                               t2 = ctree_new (MB_TERM_STLOC, csig->ret->type, t1, NULL);
+                               t1->size = offset;
+                               t2 = ctree_new (mp, MB_TERM_STLOC, csig->ret->type, t1, NULL);
                                size = mono_type_size (csig->ret, &align);
                                local_offset += align - 1;
                                local_offset &= ~(align - 1);
@@ -566,35 +606,36 @@ mono_compile_method (MonoMethod *method)
                                t2->data.i = - local_offset;
                                t2->cli_addr = fa;
                                ADD_TREE (t2);
-                               t1 = ctree_new_leaf (MB_TERM_LDLOC, t2->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, t2->type);
                                t1->data.i = t2->data.i;
                                PUSH_TREE (t1);
                        } else {
-                               t1 = ctree_new_leaf (MB_TERM_CALL, MONO_TYPE_VOID);
+                               t1 = ctree_new_leaf (mp, MB_TERM_CALL, MONO_TYPE_VOID);
                                t1->data.p = cm;
+                               t1->size = offset;
                                t1->cli_addr = fa;
                                ADD_TREE (t1);
                        }
                        break;
                }
-               case CEE_LDC_I4_S: 
+               case CEE_LDC_I4_S: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = *ip;
                        ++ip;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
-               case CEE_LDC_I4: 
+               }
+               case CEE_LDC_I4: 
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = read32 (ip);
                        ip += 4;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
+               }
                case CEE_LDC_I4_M1:
                case CEE_LDC_I4_0:
                case CEE_LDC_I4_1:
@@ -604,23 +645,54 @@ mono_compile_method (MonoMethod *method)
                case CEE_LDC_I4_5:
                case CEE_LDC_I4_6:
                case CEE_LDC_I4_7:
-               case CEE_LDC_I4_8:
-                       t1 = ctree_new_leaf (MB_TERM_CONST_I4, MONO_TYPE_I4);
+               case CEE_LDC_I4_8: {
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
                        t1->data.i = (*ip) - CEE_LDC_I4_0;
                        ++ip;
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
-
-               case CEE_LDC_R8: 
+               }
+               case CEE_LDNULL: {
+                       //fixme: don't know if this is portable ?
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_CONST_R8, MONO_TYPE_R8);
-                       (const void *) t1->data.p = ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I4, MONO_TYPE_I4);
+                       t1->data.i = 0;
                        t1->cli_addr = cli_addr;
+                       PUSH_TREE (t1);
+                       break;
+               }
+               case CEE_LDC_I8: {
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_I8, MONO_TYPE_I8);
+                       t1->data.l =  read64 (ip);
                        ip += 8;
+                       t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);         
                        break;
-
+               }
+               case CEE_LDC_R4: {
+                       float *f = alloc_static (sizeof (float));
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_R4, MONO_TYPE_R4);
+                       readr4 (ip, f);
+                       t1->data.p = f;
+                       t1->cli_addr = cli_addr;
+                       ip += 4;
+                       PUSH_TREE (t1);         
+                       break;
+               }
+               case CEE_LDC_R8: { 
+                       double *d = alloc_static (sizeof (double));
+                       ++ip;
+                       t1 = ctree_new_leaf (mp, MB_TERM_CONST_R8, MONO_TYPE_R8);
+                       readr8 (ip, d);
+                       t1->data.p = d;
+                       t1->cli_addr = cli_addr;
+                       ip += 8;
+                       PUSH_TREE (t1);         
+                       break;
+               }
                case CEE_LDLOC_0:
                case CEE_LDLOC_1:
                case CEE_LDLOC_2:
@@ -628,7 +700,7 @@ mono_compile_method (MonoMethod *method)
                        int n = (*ip) - CEE_LDLOC_0;
                        ++ip;
 
-                       t1 = ctree_new_leaf (MB_TERM_LDLOC, LOCAL_TYPE (n)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, LOCAL_TYPE (n)->type);
                        t1->data.i = LOCAL_POS (n);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
@@ -637,7 +709,7 @@ mono_compile_method (MonoMethod *method)
                case CEE_LDLOC_S: {
                        ++ip;
 
-                       t1 = ctree_new_leaf (MB_TERM_LDLOC, LOCAL_TYPE (*ip)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDLOC, LOCAL_TYPE (*ip)->type);
                        t1->data.i = LOCAL_POS (*ip);
                        t1->cli_addr = cli_addr;
                        ++ip;
@@ -645,7 +717,6 @@ mono_compile_method (MonoMethod *method)
                        PUSH_TREE (t1);
                        break;
                }
-
                case CEE_STLOC_0:
                case CEE_STLOC_1:
                case CEE_STLOC_2:
@@ -654,7 +725,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_STLOC, LOCAL_TYPE (n)->type, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_STLOC, LOCAL_TYPE (n)->type, *sp, NULL);
                        t1->data.i = LOCAL_POS (n);
                        t1->cli_addr = sp [0]->cli_addr;
                        ADD_TREE (t1);                  
@@ -664,7 +735,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_STLOC, LOCAL_TYPE (*ip)->type, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_STLOC, LOCAL_TYPE (*ip)->type, *sp, NULL);
                        t1->data.i = LOCAL_POS (*ip);
                        t1->cli_addr = sp [0]->cli_addr;
                        ++ip;
@@ -672,55 +743,39 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);                  
                        break;
                }
-               case CEE_ADD:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_ADD, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_SUB:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_SUB, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
 
-               case CEE_MUL:
+               MAKE_BI_ALU (ADD)
+               MAKE_BI_ALU (SUB)
+               MAKE_BI_ALU (AND)
+               MAKE_BI_ALU (OR)
+               MAKE_BI_ALU (XOR)
+                       //MAKE_BI_ALU (SHL)
+                       //MAKE_BI_ALU (SHR)
+                       //MAKE_BI_ALU (SHR_UN)
+               MAKE_BI_ALU (MUL)
+               MAKE_BI_ALU (DIV)
+                       //MAKE_BI_ALU (DIV_UN)
+                       //MAKE_BI_ALU (REM)
+                       //MAKE_BI_ALU (REM_UN)
+
+               case CEE_BR_S: {
                        ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_MUL, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_DIV:
-                       ++ip;
-                       sp -= 2;
-                       t1 = ctree_new (MB_TERM_DIV, 0, sp [0], sp [1]);
-                       t1->cli_addr = sp [0]->cli_addr;
-                       PUSH_TREE (t1);
-                       break;
-
-               case CEE_BR_S: 
-                       ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BR, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BR, 0);
                        t1->data.i = cli_addr + 2 + (signed char) *ip;
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        ++ip;
                        break;
-
-               case CEE_BR:
+               }
+               case CEE_BR: {
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_BR, 0);
+                       t1 = ctree_new_leaf (mp, MB_TERM_BR, 0);
                        t1->data.i = cli_addr + 5 + (gint32) read32(ip);
                        t1->cli_addr = cli_addr;
                        ADD_TREE (t1);
                        ip += 4;
                        break;
+               }
 
                MAKE_CJUMP(BGT)
                MAKE_CJUMP(BGT_UN)
@@ -739,7 +794,7 @@ mono_compile_method (MonoMethod *method)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_BRTRUE, 0, sp [0], NULL);
+                       t1 = ctree_new (mp, MB_TERM_BRTRUE, 0, sp [0], NULL);
 
                        if (near_jump)
                                t1->data.i = cli_addr + 2 + (signed char) *ip;
@@ -751,14 +806,13 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);
                        break;
                }
-
                case CEE_BRFALSE:
                case CEE_BRFALSE_S: {
                        int near_jump = *ip == CEE_BRFALSE_S;
                        ++ip;
                        --sp;
 
-                       t1 = ctree_new (MB_TERM_BRFALSE, 0, sp [0], NULL);
+                       t1 = ctree_new (mp, MB_TERM_BRFALSE, 0, sp [0], NULL);
 
                        if (near_jump)
                                t1->data.i = cli_addr + 2 + (signed char) *ip;
@@ -770,15 +824,15 @@ mono_compile_method (MonoMethod *method)
                        ADD_TREE (t1);
                        break;
                }
-               case CEE_RET:
+               case CEE_RET: {
                        ip++;
 
                        if (signature->ret->type != MONO_TYPE_VOID) {
                                --sp;
-                               t1 = ctree_new (MB_TERM_RETV, 0, *sp, NULL);
+                               t1 = ctree_new (mp, MB_TERM_RETV, 0, *sp, NULL);
                                t1->cli_addr = sp [0]->cli_addr;
                        } else {
-                               t1 = ctree_new (MB_TERM_RET, 0, NULL, NULL);
+                               t1 = ctree_new (mp, MB_TERM_RET, 0, NULL, NULL);
                                t1->cli_addr = cli_addr;
                        }
 
@@ -791,86 +845,85 @@ mono_compile_method (MonoMethod *method)
                                g_warning ("more values on stack: %d", sp - stack);
 
                        break;
-
+               }
                case CEE_LDARG_0:
                case CEE_LDARG_1:
                case CEE_LDARG_2:
                case CEE_LDARG_3: {
                        int n = (*ip) - CEE_LDARG_0;
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (n)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (n)->type);
                        t1->data.i = ARG_POS (n);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        break;
                }
-
-               case CEE_LDARG_S:
+               case CEE_LDARG_S: {
                        ++ip;
-                       t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (*ip)->type);
+                       t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (*ip)->type);
                        t1->data.i = ARG_POS (*ip);
                        t1->cli_addr = cli_addr;
                        PUSH_TREE (t1);
                        ++ip;
                        break;
-
-               case CEE_DUP: 
+               }
+               case CEE_DUP: {
                        ++ip; 
 
                        if (sp [-1]->op == MB_TERM_LDLOC) {
-                               t1 = ctree_new (0, 0, NULL, NULL);
+                               t1 = ctree_new (mp, 0, 0, NULL, NULL);
                                *t1 = *sp [-1];
                                PUSH_TREE (t1);         
                        } else 
                                g_assert_not_reached ();
 
                        break;
-
-               case CEE_POP:
+               }
+               case CEE_POP: {
                        ++ip;
                        --sp;
                        /*
                         * all side effects are already on the forest,
                         * so we can simply ignore this tree
                         */
-                       g_free (*sp);
+                       // we use the mompool g_free (*sp);
                        break;
-
+               }
                case CEE_CONV_U1: 
-               case CEE_CONV_I1: 
+               case CEE_CONV_I1: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I1, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I1, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case CEE_CONV_U2: 
-               case CEE_CONV_I2: 
+               case CEE_CONV_I2: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I2, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I2, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case CEE_CONV_I: 
-               case CEE_CONV_I4:
+               case CEE_CONV_I4: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I4, MONO_TYPE_I4, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I4, MONO_TYPE_I4, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
-               case CEE_CONV_I8:
+               }
+               case CEE_CONV_I8: {
                        ++ip;
                        sp--;
-                       t1 = ctree_new (MB_TERM_CONV_I8, MONO_TYPE_I8, *sp, NULL);
+                       t1 = ctree_new (mp, MB_TERM_CONV_I8, MONO_TYPE_I8, *sp, NULL);
                        t1->cli_addr = sp [0]->cli_addr;
                        PUSH_TREE (t1);         
                        break;
-              
+               }
                case 0xFE:
                        ++ip;                   
                        switch (*ip) {
@@ -879,7 +932,7 @@ mono_compile_method (MonoMethod *method)
                                ++ip;
                                n = read32 (ip);
                                ip += 4;
-                               t1 = ctree_new_leaf (MB_TERM_LDARG, ARG_TYPE (n)->type);
+                               t1 = ctree_new_leaf (mp, MB_TERM_LDARG, ARG_TYPE (n)->type);
                                t1->data.i = ARG_POS (n);
                                t1->cli_addr = cli_addr;
                                PUSH_TREE (t1);
@@ -906,6 +959,8 @@ mono_compile_method (MonoMethod *method)
        emit_method (method, &cgstat);
 
        mono_regset_free (cgstat.rs);
+       g_ptr_array_free (forest, TRUE);
+       mono_mempool_destroy (cgstat.mp);
 
        return method->addr;
 }
index 7c0e9dd82bfee115c182bd4e419161a60670108b..fbae36dda830d5572a8ad60f79e80e866a6c96e9 100644 (file)
@@ -7,18 +7,12 @@
 #include <mono/arch/x86/x86-codegen.h>
 
 #include "regset.h"
+#include "jit.h"
 
 #define MBTREE_TYPE  MBTree
 #define MBCGEN_TYPE  MBCodeGenStatus
-
-typedef struct {
-       guint8 *start;
-       guint8 *code;
-       gint32 locals_size;
-       GPtrArray *forest;
-       MonoRegSet *rs;
-       guint32 epilog;
-} MBCodeGenStatus;
+#define MBCOST_DATA  MBCodeGenStatus
+#define MBALLOC_STATE mono_mempool_alloc (data->mp, sizeof (MBState))
 
 typedef struct _MBTree MBTree;
 struct _MBTree {
@@ -39,9 +33,11 @@ struct _MBTree {
        gint8 reg1;
        gint8 reg2;
        MonoTypeEnum type;
+       gint32 size;
 
        union {
-               int i;
+               gint32 i;
+               gint64 l;
                gpointer p;
        } data;
 };
@@ -73,11 +69,12 @@ gint64 mono_lldiv  (gint64 a, gint64 b);
 #
 
 # constatnts
-%term CONST_I4 CONST_R8
+%term CONST_I4 CONST_I8 CONST_R4 CONST_R8
 %term LDLOC LDARG STLOC BR RET RETV ARG CALL BREAK
-%term ADD SUB MUL DIV
-%term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN  BLE BLE_UN BGT BGT_UN 
+%term ADD SUB MUL DIV AND OR XOR
+%term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN 
 %term CONV_I4 CONV_I1 CONV_I2 CONV_I8
+
 #
 # we start at stmt
 #
@@ -229,6 +226,24 @@ reg: SUB (reg, reg) {
        x86_alu_reg_reg (s->code, X86_SUB, tree->reg1, tree->right->reg1);
 }
 
+reg: AND (reg, reg) {
+       if (tree->reg1 != tree->left->reg1)
+               x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+       x86_alu_reg_reg (s->code, X86_AND, tree->reg1, tree->right->reg1);
+}
+
+reg: OR (reg, reg) {
+       if (tree->reg1 != tree->left->reg1)
+               x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+       x86_alu_reg_reg (s->code, X86_OR, tree->reg1, tree->right->reg1);
+}
+
+reg: XOR (reg, reg) {
+       if (tree->reg1 != tree->left->reg1)
+               x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+       x86_alu_reg_reg (s->code, X86_XOR, tree->reg1, tree->right->reg1);
+}
+
 stmt: STLOC (CONST_I4) "MB_USE_OPT1(0)" {
        x86_mov_membase_imm (s->code, X86_EBP, tree->data.i,
                             tree->left->data.i, 4);
@@ -329,6 +344,26 @@ stmt: BGT (reg, CONST_I4) "MB_USE_OPT1(0)" {
        x86_branch32 (s->code, X86_CC_GT, tree->data.i - offset, TRUE); 
 }
 
+stmt: BGT_UN (reg, reg) 1 {
+       guint8 *start = s->code;
+       gint32 offset;
+
+       tree->is_jump = 1;
+       x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
+       offset = 6 + s->code - start;
+       x86_branch32 (s->code, X86_CC_GT, tree->data.i - offset, FALSE); 
+}
+
+stmt: BGT_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
+       guint8 *start = s->code;
+       gint32 offset;
+
+       tree->is_jump = 1;
+       x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
+       offset = 6 + s->code - start;
+       x86_branch32 (s->code, X86_CC_GT, tree->data.i - offset, FALSE); 
+}
+
 stmt: BEQ (reg, CONST_I4) "MB_USE_OPT1(0)" {
        guint8 *start = s->code;
        gint32 offset;
@@ -515,6 +550,9 @@ reg: CALL {
                x86_mov_reg_imm (s->code, X86_EAX, tree->data.p);
                x86_call_membase (s->code, X86_EAX, 
                                  G_STRUCT_OFFSET (MonoMethod, addr));
+               if (tree->size)
+                       x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
+
                g_assert (tree->reg1 == X86_EAX);
                break;
        default:
@@ -534,12 +572,19 @@ reg: CALL {
 stmt: CALL {
        x86_mov_reg_imm (s->code, X86_EAX, tree->data.p);
        x86_call_membase (s->code, X86_EAX, G_STRUCT_OFFSET (MonoMethod, addr));
+       if (tree->size)
+               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
 }
 
 #
 # 64 bit integers
 #
 
+lreg: CONST_I8 1 {
+       x86_mov_reg_imm (s->code, tree->reg1, tree->data.i);
+       x86_mov_reg_imm (s->code, tree->reg2, *(gint32 *)(&tree->data.p + 4));
+}
+
 lreg: CONV_I8 (CONST_I4) 1 {
        x86_mov_reg_imm (s->code, tree->reg1, tree->left->data.i);
 
@@ -630,6 +675,8 @@ lreg: CALL {
        x86_mov_reg_imm (s->code, X86_EAX, tree->data.p);
        x86_call_membase (s->code, X86_EAX, 
                          G_STRUCT_OFFSET (MonoMethod, addr));
+       if (tree->size)
+               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
 } cost {
        MBCOND (tree->type == MONO_TYPE_I8 ||
                tree->type == MONO_TYPE_U8);
@@ -701,7 +748,10 @@ stmt: BGE (lreg, lreg) {
 
 #
 # floating point 
-# fixme: dont know how to assign registers?
+
+freg: CONST_R4 {
+       x86_fld (s->code, tree->data.p, FALSE);
+}
 
 freg: CONST_R8 {
        x86_fld (s->code, tree->data.p, TRUE);
@@ -759,6 +809,8 @@ freg: CALL {
        x86_mov_reg_imm (s->code, X86_EAX, tree->data.p);
        x86_call_membase (s->code, X86_EAX, 
                          G_STRUCT_OFFSET (MonoMethod, addr));
+       if (tree->size)
+               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
 } cost {
        MBCOND (tree->type == MONO_TYPE_R4 ||
                tree->type == MONO_TYPE_R8);
diff --git a/mono/metadata/mempool.c b/mono/metadata/mempool.c
new file mode 100644 (file)
index 0000000..2fa2bd2
--- /dev/null
@@ -0,0 +1,107 @@
+#include <config.h>
+#include <glib.h>
+
+#include "jit.h"
+
+/*
+ * MonoMemPool is for fast allocation of memory. We free
+ * all memory when the pool is destroyed.
+ */
+
+#if SIZEOF_VOID_P > SIZEOF_LONG
+#define MEM_ALIGN     SIZEOF_VOID_P
+#else
+#define MEM_ALIGN     SIZEOF_LONG
+#endif
+
+#define MONO_MEMPOOL_PAGESIZE 8192
+
+struct _MonoMemPool {
+       MonoMemPool *next;
+       gint rest;
+       gpointer pos;
+};
+
+/**
+ * mono_mempool_new:
+ *
+ * Returns: a new memory pool.
+ */
+MonoMemPool *
+mono_mempool_new ()
+{
+
+       MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
+       pool->next = NULL;
+       pool->pos = (gpointer)pool + sizeof (MonoMemPool);
+       pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+       return pool;
+}
+
+/**
+ * mono_mempool_destroy:
+ * @pool: the momory pool to destroy
+ *
+ * Free all memory associated with this pool.
+ */
+void
+mono_mempool_destroy (MonoMemPool *pool)
+{
+       MonoMemPool *p, *n;
+
+       p = pool;
+       while (p) {
+               n = p->next;
+               g_free (p);
+               p = n;
+       }
+}
+
+/**
+ * mono_mempool_alloc:
+ * @pool: the momory pool to destroy
+ * @size: size of the momory block
+ *
+ * Allocates a new block of memory in @pool. @size must 
+ * be smaller than 256.
+ *
+ * Returns: the address of a newly allocated memory block.
+ */
+gpointer
+mono_mempool_alloc (MonoMemPool *pool, guint size)
+{
+       gpointer rval;
+
+       g_assert (pool != NULL);
+       g_assert (size < 256);
+
+       size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
+
+       if (pool->rest < size) {
+               MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
+               np->next = pool->next;
+               pool->next = np;
+               pool->pos = (gpointer)np + sizeof (MonoMemPool);
+               pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+       }
+
+       rval = pool->pos;
+       pool->rest -= size;
+       pool->pos += size;
+
+       return rval;
+}
+
+/**
+ * mono_mempool_alloc0:
+ *
+ * same as mono_mempool_alloc, but fills memory with zero.
+ */
+gpointer
+mono_mempool_alloc0 (MonoMemPool *pool, guint size)
+{
+       gpointer rval = mono_mempool_alloc (pool, size);
+       memset (rval, 0, size);
+       return rval;
+}
+
index 8a4aa66ccfc4bc31a4408be0d57a08f190b84d59..bf502c0a3fa9021b81747a2c40ea99a9ee4d925a 100644 (file)
@@ -1,3 +1,11 @@
+2001-09-23  Dietmar Maurer  <dietmar@ximian.com>
+
+       * monoburg.c: add a macro MBALLOC_STATE to define the allocation 
+       function for MBState. Added an additional user data argument to
+       mono_burg_label - the data can be used in the cost functions. The
+       type can be defined with MBCOST_DATA macro.
+       (emit_cost_func): inline cost functions
+
 2001-09-22  Dietmar Maurer  <dietmar@ximian.com>
 
        * monoburg.y (strndup): removed, use g_strndup instead
index 61752b9b38ff2318b6992317de22355d3077918c..d13501d008258e22d31949a7f2c52c8c022f18fe 100644 (file)
@@ -51,7 +51,7 @@ create_rule (char *id, Tree *tree, char *code, char *cost, char *cfunc)
                if (cost)
                        yyerror ("duplicated costs (constant costs and cost function)");
                else 
-                       rule->cost = g_strdup_printf ("mono_burg_cost_%d (tree)",
+                       rule->cost = g_strdup_printf ("mono_burg_cost_%d (tree, data)",
                                                      g_list_length (rule_list));
        }
 
@@ -223,7 +223,8 @@ emit_header ()
        output ("#ifndef MBTREE_RIGHT\n#define MBTREE_RIGHT(t) ((t)->right)\n#endif\n");
        output ("#ifndef MBTREE_STATE\n#define MBTREE_STATE(t) ((t)->state)\n#endif\n");
        output ("#ifndef MBCGEN_TYPE\n#define MBCGEN_TYPE int\n#endif\n");
-
+       output ("#ifndef MBALLOC_STATE\n#define MBALLOC_STATE g_new (MBState, 1)\n#endif\n");
+       output ("#ifndef MBCOST_DATA\n#define MBCOST_DATA gpointer\n#endif\n");
        output ("\n");
        output ("#define MBMAXCOST 32768\n");
 
@@ -397,7 +398,7 @@ emit_label_func ()
        int i;
 
        output ("static MBState *\n");
-       output ("mono_burg_label_priv (MBTREE_TYPE *tree) {\n");
+       output ("mono_burg_label_priv (MBTREE_TYPE *tree, MBCOST_DATA *data) {\n");
 
        output ("\tint arity;\n");
        output ("\tint c;\n");
@@ -409,18 +410,19 @@ emit_label_func ()
        output ("\t\tright = NULL;\n");
        output ("\t\tbreak;\n");
        output ("\tcase 1:\n");
-       output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree));\n");
+       output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
        output ("\t\tright = NULL;\n");
        output ("\t\tbreak;\n");
        output ("\tcase 2:\n");
-       output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree));\n");
-       output ("\t\tright = mono_burg_label_priv (MBTREE_RIGHT(tree));\n");
+       output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
+       output ("\t\tright = mono_burg_label_priv (MBTREE_RIGHT(tree), data);\n");
        output ("\t}\n\n");
 
        output ("\tarity = (left != NULL) + (right != NULL);\n");
        output ("\tg_assert (arity == mono_burg_arity [MBTREE_OP(tree)]);\n\n");
 
-       output ("\tp = g_new0 (MBState, 1);\n");
+       output ("\tp = MBALLOC_STATE;\n");
+       output ("\tmemset (p, 0, sizeof (MBState));\n");
        output ("\tp->op = MBTREE_OP(tree);\n");
        output ("\tp->left = left;\n");
        output ("\tp->right = right;\n");
@@ -471,8 +473,8 @@ emit_label_func ()
        output ("}\n\n");
 
        output ("MBState *\n");
-       output ("mono_burg_label (MBTREE_TYPE *tree)\n{\n");
-       output ("\tMBState *p = mono_burg_label_priv (tree);\n");
+       output ("mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data)\n{\n");
+       output ("\tMBState *p = mono_burg_label_priv (tree, data);\n");
        output ("\treturn p->rule_%s ? p : NULL;\n", ((NonTerm *)nonterm_list->data)->name);
        output ("}\n\n");
 }
@@ -613,11 +615,11 @@ emit_cost_func ()
                Rule *rule = (Rule *)l->data;
                
                if (rule->cfunc) {
-                       output ("static guint16\n");
+                       output ("inline static guint16\n");
 
                        emit_rule_string (rule, "");
 
-                       output ("mono_burg_cost_%d (MBTREE_TYPE *tree)\n", i + 1);
+                       output ("mono_burg_cost_%d (MBTREE_TYPE *tree, MBCOST_DATA *data)\n", i + 1);
                        output ("{\n");
                        output ("%s\n", rule->cfunc);
                        output ("}\n\n");
@@ -752,7 +754,7 @@ emit_prototypes ()
        output ("extern guint16 *mono_burg_nts [];\n");
        output ("extern MBEmitFunc mono_burg_func [];\n");
 
-       output ("MBState *mono_burg_label (MBTREE_TYPE *tree);\n");
+       output ("MBState *mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data);\n");
        output ("int mono_burg_rule (MBState *state, int goal);\n");
        output ("MBTREE_TYPE **mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids []);\n");
 
index 334930345742851c8a296ee5859ec725f82a422b..006eca2038e065a90f0f492f54110371014cf9fc 100644 (file)
@@ -134,7 +134,7 @@ main ()
 
        t = create_tree (MB_TERM_Fetch, l, NULL);
 
-       s = mono_burg_label (t);
+       s = mono_burg_label (t, NULL);
 
        g_assert (s);