Fix for x86 and amd64 continuations
authorDolphin Hawkins <dolphin@exitzer0.com>
Thu, 16 Jun 2016 23:55:57 +0000 (16:55 -0700)
committerDolphin Hawkins <dolphin@exitzer0.com>
Thu, 16 Jun 2016 23:55:57 +0000 (16:55 -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 06c0fd710fc830a14454225d2867b41b8823f999..973fa326105c25c0c958fbebcc45c54cef8a8573 100644 (file)
@@ -1165,13 +1165,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 14e8f6111c15ce90bac97f37ab15c38b85ec27ae..df3c867f167982b16b16ecc6b59f99b9755ea459 100644 (file)
@@ -1154,8 +1154,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);
@@ -1168,10 +1170,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 901a6c99d76554f74d5ef72cec3a828b6e0802c8..eab64ce262558e1579b4b1c74a43e72575742fe3 100644 (file)
@@ -7442,7 +7442,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 3159149307040796ecef73de4c5a6fc3ae92d7e5..7452864b101efb491e0b332de19dfbc1201717d9 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) {