2002-05-15 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Wed, 15 May 2002 06:16:23 +0000 (06:16 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Wed, 15 May 2002 06:16:23 +0000 (06:16 -0000)
* jit.c (mono_analyze_flow): try blocks are followed by handler
blocks, so we need to add all handler blocks as succesors.

* exception.c (arch_handle_exception): correctly save/restore caller
saved regs.

* emit-x86.c (arch_emit_prologue): correctly save/restore caller
saved regs.

* jit.c (mono_cfg_new): allocate space for caller saved registers.

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

mono/jit/ChangeLog
mono/jit/emit-x86.c
mono/jit/exception.c
mono/jit/jit.c

index 4a343421f8d234e8014a209b56c293ce52ef5e4d..34faf5c519ccc5bb4814c47beca68b891f8ed8bc 100644 (file)
@@ -1,3 +1,16 @@
+2002-05-15  Dietmar Maurer  <dietmar@ximian.com>
+
+       * jit.c (mono_analyze_flow): try blocks are followed by handler
+       blocks, so we need to add all handler blocks as succesors.
+
+       * exception.c (arch_handle_exception): correctly save/restore caller
+       saved regs.
+
+       * emit-x86.c (arch_emit_prologue): correctly save/restore caller
+       saved regs.
+
+       * jit.c (mono_cfg_new): allocate space for caller saved registers.
+
 2002-05-14  Dietmar Maurer  <dietmar@ximian.com>
 
        * jit.c: only use one TLS slot to store jit data
index 6d66956c94bc58065887bb76d7f5a93b773e6a0b..ff5204b26ca0e72c9e2db6309ff63e64b4c93230 100644 (file)
@@ -291,22 +291,30 @@ arch_emit_prologue (MonoFlowGraph *cfg)
 {
        MonoMethod *method = cfg->method;
        MonoMethodHeader *header = ((MonoMethodNormal *)method)->header;
-       int i, j, k;
+       int i, j, k, alloc_size;
 
        x86_push_reg (cfg->code, X86_EBP);
        x86_mov_reg_reg (cfg->code, X86_EBP, X86_ESP, 4);
 
-       if (cfg->locals_size)
-               x86_alu_reg_imm (cfg->code, X86_SUB, X86_ESP, cfg->locals_size);
+       alloc_size = cfg->locals_size;
 
-       if (mono_regset_reg_used (cfg->rs, X86_EBX)) 
+       if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
                x86_push_reg (cfg->code, X86_EBX);
+               alloc_size -= 4;
+       }
 
-       if (mono_regset_reg_used (cfg->rs, X86_EDI)) 
+       if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
                x86_push_reg (cfg->code, X86_EDI);
+               alloc_size -= 4;
+       }
 
-       if (mono_regset_reg_used (cfg->rs, X86_ESI))
+       if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
                x86_push_reg (cfg->code, X86_ESI);
+               alloc_size -= 4;
+       }
+
+       if (alloc_size)
+               x86_alu_reg_imm (cfg->code, X86_SUB, X86_ESP, alloc_size);
 
        if (mono_jit_trace_calls) {
                x86_push_reg (cfg->code, X86_EBP);
@@ -339,6 +347,9 @@ arch_emit_prologue (MonoFlowGraph *cfg)
                        int size = - offset;
                        int inited = 0;
                        
+                       /* do not clear caller saved registers */
+                       size -= 12;
+
                        for (i = 0; i < header->num_locals; ++i) {
                                MonoVarInfo *rv = &VARINFO (cfg, cfg->locals_start_index + i);
 
@@ -430,7 +441,7 @@ arch_emit_prologue (MonoFlowGraph *cfg)
 static void
 arch_emit_epilogue (MonoFlowGraph *cfg)
 {
-       int pos = 4;
+       int pos;
        /*
         * note: with trace and profiling the value on the FP stack may get clobbered.
         */
@@ -459,17 +470,18 @@ arch_emit_epilogue (MonoFlowGraph *cfg)
                x86_pop_reg (cfg->code, X86_EAX);
        }
 
+       pos = -4;
        if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
-               x86_mov_reg_membase (cfg->code, X86_EBX, X86_EBP, - (cfg->locals_size + pos), 4);
-               pos += 4;
+               x86_mov_reg_membase (cfg->code, X86_EBX, X86_EBP, pos, 4);
+               pos -= 4;
        }
        if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
-               x86_mov_reg_membase (cfg->code, X86_EDI, X86_EBP, - (cfg->locals_size + pos), 4);
-               pos += 4;
+               x86_mov_reg_membase (cfg->code, X86_EDI, X86_EBP, pos, 4);
+               pos -= 4;
        }
        if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
-               x86_mov_reg_membase (cfg->code, X86_ESI, X86_EBP, - (cfg->locals_size + pos), 4);
-               pos += 4;
+               x86_mov_reg_membase (cfg->code, X86_ESI, X86_EBP, pos, 4);
+               pos -= 4;
        }
 
        x86_leave (cfg->code);
index 1dac4bda09884bf52496da23c6a10e1ed24efc21..7becf60025c57072e4396b6a1ee210f88a3b54cb 100644 (file)
@@ -168,7 +168,7 @@ arch_handle_exception (struct sigcontext *ctx, gpointer obj)
 
        if (ji) { /* we are inside managed code */
                MonoMethod *m = ji->method;
-               int offset = 2;
+               int offset;
 
                if (ji->num_clauses) {
                        int i;
@@ -224,17 +224,18 @@ arch_handle_exception (struct sigcontext *ctx, gpointer obj)
 
                /* continue unwinding */
 
+               offset = -1;
                /* restore caller saved registers */
                if (ji->used_regs & X86_ESI_MASK) {
-                       ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
-                       offset++;
+                       ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
+                       offset--;
                }
                if (ji->used_regs & X86_EDI_MASK) {
                        ctx->SC_EDI = *((int *)ctx->SC_EBP + offset);
-                       offset++;
+                       offset--;
                }
                if (ji->used_regs & X86_EBX_MASK) {
-                       ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
+                       ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
                }
 
                ctx->SC_ESP = ctx->SC_EBP;
index d68eba414635bafc4ea086f4c106ad938d5c5199..4e79ed97dfccfb572abe04bb10a7a9291f36aa9a 100644 (file)
@@ -1056,6 +1056,10 @@ mono_cfg_new (MonoMethod *method, MonoMemPool *mp)
        cfg->method = method;
        cfg->mp = mp;
 
+       /* reserve space for caller saved registers */
+       /* fixme: this is arch dependent */
+       cfg->locals_size = 12;
+
        /* fixme: we should also consider loader optimisation attributes */
        cfg->share_code = mono_jit_share_code;
 
@@ -1295,6 +1299,15 @@ mono_analyze_flow (MonoFlowGraph *cfg)
        cfg->bblocks = bblocks;
        cfg->block_count = block_count;
        
+       for (i = 0; i < header->num_clauses; ++i) {
+               MonoBBlock *sbb, *tbb;
+               clause = &header->clauses [i];
+               sbb = &cfg->bblocks [bcinfo [clause->try_offset].block_id];
+               tbb = &cfg->bblocks [bcinfo [clause->handler_offset].block_id];
+               g_assert (sbb && tbb);
+               sbb->succ = g_list_prepend (sbb->succ, tbb);
+       }
+
        ip = header->code;
        end = ip + header->code_size;
        bb = NULL;