Fri Sep 26 17:00:46 CEST 2008 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Fri, 26 Sep 2008 15:02:35 +0000 (15:02 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Fri, 26 Sep 2008 15:02:35 +0000 (15:02 -0000)
* mini-amd64.c, mini-amd64.h, tramp-amd64.c: amd64 support code for calling a
runtime-set function when going back to managed code. Currently this
is used to set back the protection on the soft ovf pages and/or to
throw the stack overflow exception that happened in unmanaged code.

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

mono/mini/ChangeLog
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h
mono/mini/tramp-amd64.c

index fd9ca0aa35b3ad34d672cea92b9933c78d50e5f5..1bf81430c2404175613cdc8fd0a8b269c4bb40f5 100644 (file)
@@ -1,4 +1,11 @@
 
+Fri Sep 26 17:00:46 CEST 2008 Paolo Molaro <lupus@ximian.com>
+
+       * mini-amd64.c, mini-amd64.h, tramp-amd64.c: amd64 support code for calling a
+       runtime-set function when going back to managed code. Currently this
+       is used to set back the protection on the soft ovf pages and/or to
+       throw the stack overflow exception that happened in unmanaged code.
+
 Fri Sep 26 16:46:23 CEST 2008 Paolo Molaro <lupus@ximian.com>
 
        * tramp-x86.c, mini-x86.h, mini-x86.c: x86 support code for calling a
index a612c44122e486a74e76fec0742d5236657b9a89..366b91df8ec26b5ae4bb2e6e64e60dc9179ae1f8 100644 (file)
@@ -5320,6 +5320,23 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        pos = 0;
        
        if (method->save_lmf) {
+               /* check if we need to restore protection of the stack after a stack overflow */
+               if (mono_get_jit_tls_offset () != -1) {
+                       guint8 *patch;
+                       code = emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+                       /* we load the value in a separate instruction: this mechanism may be
+                        * used later as a safer way to do thread interruption
+                        */
+                       amd64_mov_reg_membase (code, X86_ECX, X86_ECX, G_STRUCT_OFFSET (MonoJitTlsData, restore_stack_prot), 8);
+                       x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0);
+                       patch = code;
+                       x86_branch8 (code, X86_CC_Z, 0, FALSE);
+                       /* note that the call trampoline will preserve eax/edx */
+                       x86_call_reg (code, X86_ECX);
+                       x86_patch (patch, code);
+               } else {
+                       /* FIXME: maybe save the jit tls in the prolog */
+               }
                if ((lmf_tls_offset != -1) && !optimize_for_xen) {
                        /*
                         * Optimized version which uses the mono_lmf TLS variable instead of indirection
@@ -5401,6 +5418,23 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                for (quad = 0; quad < 2; quad ++) {
                        switch (ainfo->pair_storage [quad]) {
                        case ArgInIReg:
+               /* check if we need to restore protection of the stack after a stack overflow */
+               if (mono_get_jit_tls_offset () != -1) {
+                       guint8 *patch;
+                       code = emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+                       /* we load the value in a separate instruction: this mechanism may be
+                        * used later as a safer way to do thread interruption
+                        */
+                       x86_mov_reg_membase (code, X86_ECX, X86_ECX, G_STRUCT_OFFSET (MonoJitTlsData, restore_stack_prot), 4);
+                       x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0);
+                       patch = code;
+                       x86_branch8 (code, X86_CC_Z, 0, FALSE);
+                       /* note that the call trampoline will preserve eax/edx */
+                       x86_call_reg (code, X86_ECX);
+                       x86_patch (patch, code);
+               } else {
+                       /* FIXME: maybe save the jit tls in the prolog */
+               }
                                amd64_mov_reg_membase (code, ainfo->pair_regs [quad], inst->inst_basereg, inst->inst_offset + (quad * sizeof (gpointer)), sizeof (gpointer));
                                break;
                        case ArgInFloatSSEReg:
index 6a1278ad772c20e02e038355821c4759616e8f9f..a40165c3c5ed7cdbb4aef4c2caf0d3a8837e7e40 100644 (file)
@@ -76,6 +76,8 @@ struct sigcontext {
 
 #define MONO_ARCH_SIGNAL_STACK_SIZE (16 * 1024)
 
+#define MONO_ARCH_HAVE_RESTORE_STACK_SUPPORT 1
+
 #define MONO_ARCH_CPU_SPEC amd64_desc
 
 #define MONO_MAX_IREGS 16
index 3207051d127b7a0f786144b7ef155bc56453bf8c..74bbe89299dd9b837e75402e5555e4fe3af90ac5 100644 (file)
@@ -456,11 +456,15 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
        for (i = 0; i < 8; ++i)
                amd64_movsd_reg_membase (code, i, AMD64_RBP, saved_fpregs_offset + (i * 8));
 
+       if (tramp_type == MONO_TRAMPOLINE_RESTORE_STACK_PROT)
+               amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RBP, saved_regs_offset + (AMD64_RAX * 8), 8);
+
        /* Restore stack */
        amd64_leave (code);
 
        if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT ||
                        tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT ||
+                       tramp_type == MONO_TRAMPOLINE_RESTORE_STACK_PROT ||
                        tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
                amd64_ret (code);
        else {