Flush
[mono.git] / mono / jit / emit-x86.c
index b16cf88a675f3fb4ad98994f06959a661f83411a..bbeb063383d03203698b71619751883ce50e694c 100644 (file)
@@ -24,7 +24,6 @@
 #include "jit.h"
 #include "helpers.h"
 #include "codegen.h"
-#include "debug.h"
 
 
 //#define DEBUG_REGALLOC
@@ -185,6 +184,9 @@ enter_method (MonoMethod *method, char *ebp)
 
        sig = method->signature;
 
+       if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
+               g_assert (!sig->pinvoke);
+
        arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1));
 
        arch_get_argument_info (sig, sig->param_count, arg_info);
@@ -417,31 +419,31 @@ arch_emit_prologue (MonoFlowGraph *cfg)
                x86_push_membase (cfg->code, X86_EAX, 0);
                /* *(lmf) = ESP */
                x86_mov_membase_reg (cfg->code, X86_EAX, 0, X86_ESP, 4);
-       }
+       } else {
 
 #if 0
-       /* activation frame alignment check */
-       x86_mov_reg_reg (cfg->code, X86_EAX, X86_ESP, 4);
-       x86_alu_reg_imm (cfg->code, X86_AND, X86_EAX, MONO_FRAME_ALIGNMENT - 1);
-       x86_alu_reg_imm (cfg->code, X86_CMP, X86_EAX, 0);
-       x86_branch32 (cfg->code, X86_CC_EQ, 1, FALSE);
-       x86_breakpoint (cfg->code);
-
+               /* activation frame alignment check */
+               x86_mov_reg_reg (cfg->code, X86_EAX, X86_ESP, 4);
+               x86_alu_reg_imm (cfg->code, X86_AND, X86_EAX, MONO_FRAME_ALIGNMENT - 1);
+               x86_alu_reg_imm (cfg->code, X86_CMP, X86_EAX, 0);
+               x86_branch32 (cfg->code, X86_CC_EQ, 1, FALSE);
+               x86_breakpoint (cfg->code);
 #endif
 
-       if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
-               x86_push_reg (cfg->code, X86_EBX);
-               pos += 4;
-       }
+               if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
+                       x86_push_reg (cfg->code, X86_EBX);
+                       pos += 4;
+               }
 
-       if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
-               x86_push_reg (cfg->code, X86_EDI);
-               pos += 4;
-       }
+               if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
+                       x86_push_reg (cfg->code, X86_EDI);
+                       pos += 4;
+               }
 
-       if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
-               x86_push_reg (cfg->code, X86_ESI);
-               pos += 4;
+               if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
+                       x86_push_reg (cfg->code, X86_ESI);
+                       pos += 4;
+               }
        }
 
        alloc_size -= pos;
@@ -603,29 +605,25 @@ arch_emit_epilogue (MonoFlowGraph *cfg)
                x86_pop_reg (cfg->code, X86_EAX);
        }
 
+       pos = 0;
+       
        if (cfg->method->save_lmf) {
-               pos = -sizeof (MonoLMF) - 4;
-       } else
-               pos = -4;
-
-       if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
-               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, pos, 4);
-               pos -= 4;
+               pos = -sizeof (MonoLMF);
+       } else {
+               if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
+                       pos -= 4;
        }
-       if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
-               x86_mov_reg_membase (cfg->code, X86_ESI, X86_EBP, pos, 4);
-               pos -= 4;
+               if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
+                       pos -= 4;
+               }
+               if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
+                       pos -= 4;
+               }
        }
-
-       if (cfg->method->save_lmf) {
-               pos = -sizeof (MonoLMF);
-
+       if (pos)
                x86_lea_membase (cfg->code, X86_ESP, X86_EBP, pos);
 
+       if (cfg->method->save_lmf) {
                /* ebx = previous_lmf */
                x86_pop_reg (cfg->code, X86_EBX);
                /* edi = lmf */
@@ -642,6 +640,17 @@ arch_emit_epilogue (MonoFlowGraph *cfg)
                x86_pop_reg (cfg->code, X86_EDI);
                x86_pop_reg (cfg->code, X86_EBX);
 
+       } else {
+
+               if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
+                       x86_pop_reg (cfg->code, X86_ESI);
+               }
+               if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
+                       x86_pop_reg (cfg->code, X86_EDI);
+               }
+               if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
+                       x86_pop_reg (cfg->code, X86_EBX);
+               }
        }
 
        x86_leave (cfg->code);
@@ -718,8 +727,6 @@ mono_label_cfg (MonoFlowGraph *cfg)
                        mbstate =  mono_burg_label (t1, cfg);
 
                        if (!mbstate) {
-                               if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
-                                       return FALSE;
                                g_warning ("tree does not match in %s: 0x%04x",
                                           mono_method_full_name (cfg->method, TRUE), t1->cli_addr);
                                mono_print_ctree (cfg, t1); printf ("\n\n");
@@ -1224,6 +1231,7 @@ arch_jit_compile_cfg (MonoDomain *target_domain, MonoFlowGraph *cfg)
        MonoJitInfo *ji;
        guint32 ls_used_mask = 0;
        MonoMethod *method = cfg->method;
+       int offset, gap;
 
        ji = mono_mempool_alloc0 (target_domain->mp, sizeof (MonoJitInfo));
                
@@ -1264,6 +1272,21 @@ arch_jit_compile_cfg (MonoDomain *target_domain, MonoFlowGraph *cfg)
        arch_emit_epilogue (cfg);               
        cfg->epilogue_end = cfg->code - cfg->start;
 
+       offset = cfg->code - cfg->start;
+       gap = cfg->code_size - offset;
+       if (gap > 0) {
+               char *org = cfg->start;
+#if 0
+               cfg->start = g_realloc (cfg->start, offset);
+#else
+               cfg->start = mono_mempool_alloc (target_domain->code_mp, offset);
+               memcpy (cfg->start, org, offset);
+               g_free (org);
+#endif
+               cfg->code_size = offset;
+               cfg->code = cfg->start + offset;
+       }
+
        mono_compute_branches (cfg);
 
        ji->code_size = cfg->code - cfg->start;