2007-07-22 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 22 Jul 2007 18:36:50 +0000 (18:36 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 22 Jul 2007 18:36:50 +0000 (18:36 -0000)
* mini-x86.h (MonoLMF): Add an 'esp' field plus comments.

* mini-x86.c (mono_arch_emit_prolog): Update after changes to the LMF structure.
* tramp-x86.c (mono_arch_create_trampoline_code): Ditto.

* exceptions-x86.c (mono_arch_get_jit_info): Properly clean up the stack after
JIT compilation throws an exception. Fixes #82050.

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

mono/mini/ChangeLog
mono/mini/exceptions-x86.c
mono/mini/mini-x86.c
mono/mini/mini-x86.h
mono/mini/tramp-x86.c

index 02ad318f3f7ecd2dcf0b1748e7615e6be61a5384..7b7893203727fe4789d0c5b7496ab3987dd1cc6d 100644 (file)
@@ -1,3 +1,13 @@
+2007-07-22  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-x86.h (MonoLMF): Add an 'esp' field plus comments.
+
+       * mini-x86.c (mono_arch_emit_prolog): Update after changes to the LMF structure.
+       * tramp-x86.c (mono_arch_create_trampoline_code): Ditto.
+
+       * exceptions-x86.c (mono_arch_get_jit_info): Properly clean up the stack after
+       JIT compilation throws an exception. Fixes #82050.
+
 2007-07-19  Mark Probst  <mark.probst@gmail.com>
 
        * mini.c: Removed the MonoLoaderErrorKind enum and replaced it
index 9e47ad1a68a65d8becba8481b4d5d469037ea853..193f059acd7d06d1302a88d97c637b36f2922584 100644 (file)
@@ -623,7 +623,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
 
                if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
                        /* remove any unused lmf */
-                       *lmf = (*lmf)->previous_lmf;
+                       *lmf = (gpointer)(((guint32)(*lmf)->previous_lmf) & ~1);
                }
 
                /* Pop EBP and the return address */
@@ -660,11 +660,27 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                new_ctx->ebx = (*lmf)->ebx;
                new_ctx->ebp = (*lmf)->ebp;
                new_ctx->eip = (*lmf)->eip;
-               /* the lmf is always stored on the stack, so the following
-                * expression points to a stack location which can be used as ESP */
-               new_ctx->esp = (unsigned long)&((*lmf)->eip);
 
-               *lmf = (*lmf)->previous_lmf;
+               /* Check if we are in a trampoline LMF frame */
+               if ((guint32)((*lmf)->previous_lmf) & 1) {
+                       /* lmf->esp is set by the trampoline code */
+                       new_ctx->esp = (*lmf)->esp;
+
+                       /* Pop arguments off the stack */
+                       {
+                               MonoMethod *method = (*lmf)->method;
+                               MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (method)->param_count + 1);
+
+                               guint32 stack_to_pop = mono_arch_get_argument_info (mono_method_signature (method), mono_method_signature (method)->param_count, arg_info);
+                               new_ctx->esp += stack_to_pop;
+                       }
+               }
+               else
+                       /* the lmf is always stored on the stack, so the following
+                        * expression points to a stack location which can be used as ESP */
+                       new_ctx->esp = (unsigned long)&((*lmf)->eip);
+
+               *lmf = (gpointer)(((guint32)(*lmf)->previous_lmf) & ~1);
 
                return ji ? ji : res;
        }
index 95e2cb0edfb90fca4949abc1a50a8dbea3c0e68e..37594eea717f1e95792e497c72f0f1d10001412e 100644 (file)
@@ -3594,8 +3594,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        /* %eax = previous_lmf */
                        x86_prefix (code, X86_GS_PREFIX);
                        x86_mov_reg_mem (code, X86_EAX, lmf_tls_offset, 4);
-                       /* skip method_info + lmf */
-                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 8);
+                       /* skip esp + method_info + lmf */
+                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 12);
                        /* push previous_lmf */
                        x86_push_reg (code, X86_EAX);
                        /* new lmf = ESP */
@@ -3620,8 +3620,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_get_lmf_addr");
                        }
 
-                       /* Skip method info */
-                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 4);
+                       /* Skip esp + method info */
+                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 8);
 
                        /* push lmf */
                        x86_push_reg (code, X86_EAX); 
index 5ee62f0c1a88b029baa57e62aa776072998ca5ac..d00811c7eeaca48c54f8f9fb3e2e3c32af5d5b8e 100644 (file)
@@ -115,9 +115,13 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep);
 #define inst_sreg2_high sreg2>>3
 
 struct MonoLMF {
-       gpointer    previous_lmf;
+       /* Offset by 1 if this is a trampoline LMF frame */
+       guint32    previous_lmf;
        gpointer    lmf_addr;
+       /* Only set in trampoline LMF frames */
        MonoMethod *method;
+       /* Only set in trampoline LMF frames */
+       guint32     esp;
        guint32     ebx;
        guint32     edi;
        guint32     esi;
index 94c8e0b723057ceecd8589723857bfd8fd84aed4..5612cfac9998057ef862bba426d4ba8f446526a3 100644 (file)
@@ -196,6 +196,11 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 
        pushed_args = 8;
 
+       /* Align stack on apple */
+       x86_alu_reg_imm (buf, X86_SUB, X86_ESP, 4);
+
+       pushed_args ++;
+
        /* save LMF begin */
 
        /* save the IP (caller ip) */
@@ -213,25 +218,33 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 
        pushed_args += 4;
 
+       /* save ESP */
+       x86_push_reg (buf, X86_ESP);
+       /* Adjust ESP so it points to the previous frame */
+       x86_alu_membase_imm (buf, X86_ADD, X86_ESP, 0, (pushed_args + 2) * 4);
+
+       pushed_args ++;
+
        /* save method info */
        x86_push_membase (buf, X86_ESP, pushed_args * sizeof (gpointer));
 
        pushed_args++;
 
-       /* the stack is correctly aligned to 16 bytes because pushed_args is 14
-        * and there is the extra trampoline arg + the return ip pushed by call
+       /* On apple, the stack is correctly aligned to 16 bytes because pushed_args is
+        * 16 and there is the extra trampoline arg + the return ip pushed by call
         * FIXME: Note that if an exception happens while some args are pushed
         * on the stack, the stack will be misaligned.
         */
-#ifdef __APPLE__
-       g_assert (pushed_args == 14);
-#endif
+       g_assert (pushed_args == 16);
+
        /* get the address of lmf for the current thread */
        x86_call_code (buf, mono_get_lmf_addr);
        /* push lmf */
        x86_push_reg (buf, X86_EAX); 
        /* push *lfm (previous_lmf) */
        x86_push_membase (buf, X86_EAX, 0);
+       /* Signal to mono_arch_find_jit_info () that this is a trampoline frame */
+       x86_alu_membase_imm (buf, X86_ADD, X86_ESP, 0, 1);
        /* *(lmf) = ESP */
        x86_mov_membase_reg (buf, X86_EAX, 0, X86_ESP, 4);
        /* save LFM end */
@@ -297,12 +310,15 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
        /* restore LMF start */
        /* ebx = previous_lmf */
        x86_pop_reg (buf, X86_EBX);
+       x86_alu_reg_imm (buf, X86_SUB, X86_EBX, 1);
        /* edi = lmf */
        x86_pop_reg (buf, X86_EDI);
        /* *(lmf) = previous_lmf */
        x86_mov_membase_reg (buf, X86_EDI, 0, X86_EBX, 4);
        /* discard method info */
        x86_pop_reg (buf, X86_ESI);
+       /* discard ESP */
+       x86_pop_reg (buf, X86_ESI);
        /* restore caller saved regs */
        x86_pop_reg (buf, X86_EBX);
        x86_pop_reg (buf, X86_EDI);
@@ -317,8 +333,8 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
        x86_mov_reg_membase (buf, X86_ECX, X86_ESP, 1 * 4, 4);
        x86_mov_reg_membase (buf, X86_EDX, X86_ESP, 2 * 4, 4);
 
-       /* Pop saved reg array + method ptr */
-       x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 9 * 4);
+       /* Pop saved reg array + stack align + method ptr */
+       x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 10 * 4);
 
        if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT)
                x86_ret (buf);