From b5702212bb6fb98f7801080665d7db11f0c1e64a Mon Sep 17 00:00:00 2001 From: Dolphin Hawkins Date: Thu, 16 Jun 2016 16:55:57 -0700 Subject: [PATCH] Fix for x86 and amd64 continuations --- mono/mini/exceptions-amd64.c | 10 ++++++---- mono/mini/exceptions-x86.c | 10 +++++----- mono/mini/mini-amd64.c | 7 ++++++- mono/mini/mini.h | 10 +++++++++- mono/mini/tasklets.c | 1 + 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index 06c0fd710fc..973fa326105 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -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)); diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index 14e8f6111c1..df3c867f167 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -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); diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 901a6c99d76..eab64ce2625 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -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); diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 31591493070..7452864b101 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -75,8 +75,16 @@ #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 diff --git a/mono/mini/tasklets.c b/mono/mini/tasklets.c index 9457633bafc..08deb0c00f2 100644 --- a/mono/mini/tasklets.c +++ b/mono/mini/tasklets.c @@ -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) { -- 2.25.1