return code;
}
-#ifdef __APPLE__
+#ifdef TARGET_MACH
static int tls_gs_offset;
#endif
mono_arch_have_fast_tls (void)
{
#ifdef TARGET_MACH
- static gboolean have_tls_get = FALSE;
+ static gboolean have_fast_tls = FALSE;
static gboolean inited = FALSE;
+ guint32 *ins;
+ if (mini_get_debug_options ()->use_fallback_tls)
+ return FALSE;
if (inited)
- return have_tls_get;
-
-#ifdef MONO_HAVE_FAST_TLS
- guint32 *ins;
+ return have_fast_tls;
ins = (guint32*)pthread_getspecific;
/*
* mov 0x4(%esp),%eax
* mov %gs:[offset](,%eax,4),%eax
*/
- have_tls_get = ins [0] == 0x0424448b && ins [1] == 0x85048b65;
+ have_fast_tls = ins [0] == 0x0424448b && ins [1] == 0x85048b65;
tls_gs_offset = ins [2];
-#endif
-
inited = TRUE;
- return have_tls_get;
+ return have_fast_tls;
#elif defined(TARGET_ANDROID)
return FALSE;
#else
+ if (mini_get_debug_options ()->use_fallback_tls)
+ return FALSE;
return TRUE;
#endif
}
static guint8*
-mono_x86_emit_tls_set (guint8* code, int sreg, int tls_offset)
-{
-#if defined(__APPLE__)
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_mem_reg (code, tls_gs_offset + (tls_offset * 4), sreg, 4);
-#elif defined(TARGET_WIN32)
- g_assert_not_reached ();
-#else
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_mem_reg (code, tls_offset, sreg, 4);
-#endif
- return code;
-}
-
-/*
- * mono_x86_emit_tls_get:
- * @code: buffer to store code to
- * @dreg: hard register where to place the result
- * @tls_offset: offset info
- *
- * mono_x86_emit_tls_get emits in @code the native code that puts in
- * the dreg register the item in the thread local storage identified
- * by tls_offset.
- *
- * Returns: a pointer to the end of the stored code
- */
-guint8*
mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset)
{
-#if defined(__APPLE__)
+#if defined(TARGET_MACH)
x86_prefix (code, X86_GS_PREFIX);
x86_mov_reg_mem (code, dreg, tls_gs_offset + (tls_offset * 4), 4);
#elif defined(TARGET_WIN32)
- /*
- * See the Under the Hood article in the May 1996 issue of Microsoft Systems
+ /*
+ * See the Under the Hood article in the May 1996 issue of Microsoft Systems
* Journal and/or a disassembly of the TlsGet () function.
*/
x86_prefix (code, X86_FS_PREFIX);
}
static guint8*
-emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
+mono_x86_emit_tls_set (guint8* code, int sreg, int tls_offset)
{
- /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
-#if defined(__APPLE__) || defined(__linux__)
- if (dreg != offset_reg)
- x86_mov_reg_reg (code, dreg, offset_reg, sizeof (mgreg_t));
+#if defined(TARGET_MACH)
x86_prefix (code, X86_GS_PREFIX);
- x86_mov_reg_membase (code, dreg, dreg, 0, sizeof (mgreg_t));
-#else
- g_assert_not_reached ();
-#endif
- return code;
-}
-
-guint8*
-mono_x86_emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
-{
- return emit_tls_get_reg (code, dreg, offset_reg);
-}
-
-static guint8*
-emit_tls_set_reg (guint8* code, int sreg, int offset_reg)
-{
- /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
-#ifdef HOST_WIN32
+ x86_mov_mem_reg (code, tls_gs_offset + (tls_offset * 4), sreg, 4);
+#elif defined(TARGET_WIN32)
g_assert_not_reached ();
-#elif defined(__APPLE__) || defined(__linux__)
- x86_prefix (code, X86_GS_PREFIX);
- x86_mov_membase_reg (code, offset_reg, 0, sreg, sizeof (mgreg_t));
#else
- g_assert_not_reached ();
+ x86_prefix (code, X86_GS_PREFIX);
+ x86_mov_mem_reg (code, tls_offset, sreg, 4);
#endif
return code;
}
-
+
/*
* emit_setup_lmf:
*
code = mono_x86_emit_tls_get (code, ins->dreg, ins->inst_offset);
break;
}
- case OP_TLS_GET_REG: {
- code = emit_tls_get_reg (code, ins->dreg, ins->sreg1);
- break;
- }
case OP_TLS_SET: {
code = mono_x86_emit_tls_set (code, ins->sreg1, ins->inst_offset);
break;
}
- case OP_TLS_SET_REG: {
- code = emit_tls_set_reg (code, ins->sreg1, ins->sreg2);
- break;
- }
case OP_MEMORY_BARRIER: {
if (ins->backend.memory_barrier_kind == MONO_MEMORY_BARRIER_SEQ) {
x86_prefix (code, X86_LOCK_PREFIX);
guint8 *patch;
/* check if we need to restore protection of the stack after a stack overflow */
- /* FIXME */
-#if 0
- if (supported) {
- if (cfg->compile_aot) {
- code = emit_load_aotconst (NULL, code, cfg, NULL, X86_ECX, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_JIT_TLS));
-
- code = emit_tls_get_reg (code, X86_ECX, X86_ECX);
- } else {
- code = mono_x86_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, MONO_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);
+ if (!cfg->compile_aot && mono_arch_have_fast_tls () && mono_tls_get_tls_offset (TLS_KEY_JIT_TLS) != -1) {
+ code = mono_x86_emit_tls_get (code, X86_ECX, mono_tls_get_tls_offset (TLS_KEY_JIT_TLS));
} else {
- /* FIXME: maybe save the jit tls in the prolog */
+ gpointer func = mono_tls_get_tls_getter (TLS_KEY_JIT_TLS, TRUE);
+ /* FIXME use tls only from IR level */
+ x86_xchg_reg_reg (code, X86_EAX, X86_ECX, 4);
+ code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, func);
+ x86_xchg_reg_reg (code, X86_EAX, X86_ECX, 4);
}
-#endif
+
+ /* 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, MONO_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);
/* restore caller saved regs */
if (cfg->used_int_regs & (1 << X86_EBX)) {