From: Dunati Date: Fri, 17 Jun 2016 02:15:14 +0000 (-0700) Subject: Fix for x86 and amd64 continuations (#3182) X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=15fedcada9e4cbad652c623e9d5bb4fd591d457b;p=mono.git Fix for x86 and amd64 continuations (#3182) --- diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index b0118726438..919682acca6 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -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)); diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index 5811210cabe..d737bc7f7f0 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -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); diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 9087f1ddbf6..073a818a514 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -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); diff --git a/mono/mini/mini.h b/mono/mini/mini.h index d9ba06ff522..ff064d11e6b 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -76,8 +76,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) {