Fix for x86 and amd64 continuations (#3182)
authorDunati <Dunati@users.noreply.github.com>
Fri, 17 Jun 2016 02:15:14 +0000 (19:15 -0700)
committerMiguel de Icaza <miguel@gnome.org>
Fri, 17 Jun 2016 02:15:14 +0000 (19:15 -0700)
mono/mini/exceptions-amd64.c
mono/mini/exceptions-x86.c
mono/mini/mini-amd64.c
mono/mini/mini.h
mono/mini/tasklets.c

index b0118726438e63ec8da7b970286721328efe0808..919682acca6a9c5fb1d2d38456f16fabb01a9227 100644 (file)
@@ -1152,13 +1152,15 @@ mono_tasklets_arch_restore (void)
        amd64_movsl (code);
 
        /* now restore the registers from the LMF */
-       NOT_IMPLEMENTED;
        amd64_mov_reg_membase (code, AMD64_RCX, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, lmf), 8);
+       amd64_mov_reg_membase (code, AMD64_RBP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rbp), 8);
        amd64_mov_reg_membase (code, AMD64_RSP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rsp), 8);
 
-       /* restore the lmf chain */
-       /*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4);
-       x86_mov_membase_reg (code, X86_ECX, 0, X86_EDX, 4);*/
+#ifdef WIN32
+       amd64_mov_reg_reg (code, AMD64_R14, AMD64_ARG_REG3, 8);
+#else
+       amd64_mov_reg_reg (code, AMD64_R12, AMD64_ARG_REG3, 8);
+#endif
 
        /* state is already in rax */
        amd64_jump_membase (code, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, return_ip));
index 5811210cabeb51ef59b2ab5c8c7de078de06e1ac..d737bc7f7f0768ab51457bf6008fda554de519d0 100644 (file)
@@ -1145,8 +1145,10 @@ mono_tasklets_arch_restore (void)
        /* the signature is: restore (MonoContinuation *cont, int state, MonoLMF **lmf_addr) */
        /* put cont in edx */
        x86_mov_reg_membase (code, X86_EDX, X86_ESP, 4, 4);
-        /* state in eax, so it's setup as the return value */
-        x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4);
+       /* state in eax, so it's setup as the return value */
+       x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4);
+       /* lmf_addr in ebx */
+       x86_mov_reg_membase(code, X86_EBX, X86_ESP, 0x0C, 4);
 
        /* setup the copy of the stack */
        x86_mov_reg_membase (code, X86_ECX, X86_EDX, MONO_STRUCT_OFFSET (MonoContinuation, stack_used_size), 4);
@@ -1159,10 +1161,8 @@ mono_tasklets_arch_restore (void)
 
        /* now restore the registers from the LMF */
        x86_mov_reg_membase (code, X86_ECX, X86_EDX, MONO_STRUCT_OFFSET (MonoContinuation, lmf), 4);
-       x86_mov_reg_membase (code, X86_EBX, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, ebx), 4);
        x86_mov_reg_membase (code, X86_EBP, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, ebp), 4);
-       x86_mov_reg_membase (code, X86_ESI, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, esi), 4);
-       x86_mov_reg_membase (code, X86_EDI, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, edi), 4);
+       x86_mov_reg_membase (code, X86_ESP, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, esp), 4);
 
        /* restore the lmf chain */
        /*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4);
index 9087f1ddbf69cf5e3e32c2a9ff72405e858b7f43..073a818a514887e4c0504042296b43a31c40d4bc 100644 (file)
@@ -7148,7 +7148,12 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        for (i = 0; i < AMD64_NREG; ++i) {
                if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->arch.saved_iregs & (1 << i))) {
                        /* Restore only used_int_regs, not arch.saved_iregs */
-                       if (cfg->used_int_regs & (1 << i)) {
+#if defined(MONO_SUPPORT_TASKLETS)
+                       int restore_reg=1;
+#else
+                       int restore_reg=(cfg->used_int_regs & (1 << i));
+#endif
+                       if (restore_reg) {
                                amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8);
                                mono_emit_unwind_op_same_value (cfg, code, i);
                                async_exc_point (code);
index d9ba06ff5225ffcfdc5f2659b6cefc4171b2c0b5..ff064d11e6bfdf72aec5527ad4473bea6c5ece40 100644 (file)
 #define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
 #endif
 
-#if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS) && defined(__GNUC__)
+#if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS)
+#if defined(__GNUC__)
 #define MONO_SUPPORT_TASKLETS 1
+#elif defined(HOST_WIN32)
+#define MONO_SUPPORT_TASKLETS 1
+// Replace some gnu intrinsics needed for tasklets with MSVC equivalents.
+#define __builtin_extract_return_addr(x) x
+#define __builtin_return_address(x) _ReturnAddress()
+#define __builtin_frame_address(x) _AddressOfReturnAddress()
+#endif
 #endif
 
 #if ENABLE_LLVM
index 9457633bafc1b81e5dcf27980522e6702e214274..08deb0c00f2913bf8c8fdccf4173ec7d5e8d768f 100644 (file)
@@ -54,6 +54,7 @@ continuation_mark_frame (MonoContinuation *cont)
 
        /* get to the frame that called Mark () */
        memset (&rji, 0, sizeof (rji));
+       memset (&ctx, 0, sizeof (ctx));
        do {
                ji = mono_find_jit_info (cont->domain, jit_tls, &rji, NULL, &ctx, &new_ctx, NULL, &lmf, NULL, NULL);
                if (!ji || ji == (gpointer)-1) {