[arm] Re-enable fast tls on all targets
[mono.git] / mono / mini / mini-arm.c
index 08808151cdf2ed65939e3cc071ac233703ac3ba2..6c58747fc5f63e8abfb8396b4c7cf18a39531516 100644 (file)
@@ -29,7 +29,7 @@
 #include "mini-gc.h"
 #include "mono/arch/arm/arm-vfp-codegen.h"
 
-#if defined(HAVE_KW_THREAD) && defined(__linux__) \
+#if (defined(HAVE_KW_THREAD) && defined(__linux__) && defined(__ARM_EABI__)) \
        || defined(TARGET_ANDROID) \
        || (defined(TARGET_IOS) && !defined(TARGET_WATCHOS))
 #define HAVE_FAST_TLS
@@ -147,8 +147,6 @@ static int vfp_scratch2 = ARM_VFP_D1;
 
 static int i8_align;
 
-static volatile int ss_trigger_var = 0;
-
 static gpointer single_step_tramp, breakpoint_tramp;
 
 /*
@@ -647,30 +645,6 @@ emit_restore_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
 
 #endif /* #ifndef DISABLE_JIT */
 
-#ifndef MONO_CROSS_COMPILE
-static gboolean
-mono_arm_have_fast_tls (void)
-{
-       if (mini_get_debug_options ()->arm_use_fallback_tls)
-               return FALSE;
-#if (defined(HAVE_KW_THREAD) && defined(__linux__)) \
-       || defined(TARGET_ANDROID)
-       guint32* kuser_get_tls = (void*)0xffff0fe0;
-       guint32 expected [] = {0xee1d0f70, 0xe12fff1e};
-
-       /* Expecting mrc + bx lr in the kuser_get_tls kernel helper */
-       return memcmp (kuser_get_tls, expected, 8) == 0;
-#elif defined(TARGET_IOS)
-       guint32 expected [] = {0x1f70ee1d, 0x0103f021, 0x0020f851, 0xbf004770};
-       /* Discard thumb bit */
-       guint32* pthread_getspecific_addr = (guint32*) ((guint32)pthread_getspecific & 0xfffffffe);
-       return memcmp ((void*)pthread_getspecific_addr, expected, 16) == 0;
-#else
-       return FALSE;
-#endif
-}
-#endif
-
 /*
  * mono_arm_have_tls_get:
  *
@@ -919,7 +893,6 @@ mono_arch_init (void)
 
        mono_mutex_init_recursive (&mini_arch_mutex);
        if (mini_get_debug_options ()->soft_breakpoints) {
-               single_step_tramp = mini_get_single_step_trampoline ();
                breakpoint_tramp = mini_get_breakpoint_trampoline ();
        } else {
                ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
@@ -1636,7 +1609,10 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                                        ainfo->reg = fpr;
                                        ainfo->nregs = nfields;
                                        ainfo->esize = esize;
-                                       fpr += nfields;
+                                       if (esize == 4)
+                                               fpr += nfields;
+                                       else
+                                               fpr += nfields * 2;
                                        break;
                                } else {
                                        fpr = ARM_VFP_F16;
@@ -1999,20 +1975,9 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                offset += size;
        }
 
-       if (cfg->arch.seq_point_read_var) {
+       if (cfg->arch.seq_point_ss_method_var) {
                MonoInst *ins;
 
-               ins = cfg->arch.seq_point_read_var;
-
-               size = 4;
-               align = 4;
-               offset += align - 1;
-               offset &= ~(align - 1);
-               ins->opcode = OP_REGOFFSET;
-               ins->inst_basereg = cfg->frame_reg;
-               ins->inst_offset = offset;
-               offset += size;
-
                ins = cfg->arch.seq_point_ss_method_var;
                size = 4;
                align = 4;
@@ -2203,9 +2168,7 @@ mono_arch_create_vars (MonoCompile *cfg)
 
        if (cfg->gen_sdb_seq_points) {
                if (cfg->soft_breakpoints) {
-                       MonoInst *ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-                       ins->flags |= MONO_INST_VOLATILE;
-                       cfg->arch.seq_point_read_var = ins;
+                       MonoInst *ins;
 
                        ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                        ins->flags |= MONO_INST_VOLATILE;
@@ -2305,7 +2268,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                case RegTypeIRegPair:
                case RegTypeBase:
                case RegTypeBaseGen:
-                       linfo->args [i].storage = LLVMArgInIReg;
+                       linfo->args [i].storage = LLVMArgNormal;
                        break;
                case RegTypeStructByVal:
                        linfo->args [i].storage = LLVMArgAsIArgs;
@@ -2641,7 +2604,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
 
                                call->float_args = g_slist_append_mempool (cfg->mempool, call->float_args, fad);
                        } else {
-                               add_outarg_reg (cfg, call, RegTypeFP, ainfo->reg + i, load);
+                               add_outarg_reg (cfg, call, RegTypeFP, ainfo->reg + (i * 2), load);
                        }
                }
                break;
@@ -4614,7 +4577,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        int i;
                        MonoInst *info_var = cfg->arch.seq_point_info_var;
                        MonoInst *ss_trigger_page_var = cfg->arch.ss_trigger_page_var;
-                       MonoInst *ss_read_var = cfg->arch.seq_point_read_var;
                        MonoInst *ss_method_var = cfg->arch.seq_point_ss_method_var;
                        MonoInst *bp_method_var = cfg->arch.seq_point_bp_method_var;
                        MonoInst *var;
@@ -4635,7 +4597,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                g_assert (arm_is_imm12 (info_var->inst_offset));
                        }
 
-                       if (!cfg->soft_breakpoints) {
+                       if (!cfg->soft_breakpoints && !cfg->compile_aot) {
                                /*
                                 * Read from the single stepping trigger page. This will cause a
                                 * SIGSEGV when single stepping is enabled.
@@ -4647,8 +4609,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
                                if (cfg->soft_breakpoints) {
-                                       /* Load the address of the sequence point trigger variable. */
-                                       var = ss_read_var;
+                                       /* Load the address of the sequence point method variable. */
+                                       var = ss_method_var;
                                        g_assert (var);
                                        g_assert (var->opcode == OP_REGOFFSET);
                                        g_assert (arm_is_imm12 (var->inst_offset));
@@ -4657,14 +4619,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                        /* Read the value and check whether it is non-zero. */
                                        ARM_LDR_IMM (code, dreg, dreg, 0);
                                        ARM_CMP_REG_IMM (code, dreg, 0, 0);
-
-                                       /* Load the address of the sequence point method. */
-                                       var = ss_method_var;
-                                       g_assert (var);
-                                       g_assert (var->opcode == OP_REGOFFSET);
-                                       g_assert (arm_is_imm12 (var->inst_offset));
-                                       ARM_LDR_IMM (code, dreg, var->inst_basereg, var->inst_offset);
-
                                        /* Call it conditionally. */
                                        ARM_BLX_REG_COND (code, ARMCOND_NE, dreg);
                                } else {
@@ -6007,15 +5961,17 @@ mono_arch_register_lowlevel_calls (void)
 
 #ifndef MONO_CROSS_COMPILE
        if (mono_arm_have_tls_get ()) {
-               if (mono_arm_have_fast_tls ()) {
-                       mono_register_jit_icall (mono_fast_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
-                       mono_register_jit_icall (mono_fast_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
+               MonoTlsImplementation tls_imp = mono_arm_get_tls_implementation ();
+
+               mono_register_jit_icall (tls_imp.get_tls_thunk, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
+               mono_register_jit_icall (tls_imp.set_tls_thunk, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
 
+               if (tls_imp.get_tls_thunk_end) {
                        mono_tramp_info_register (
                                mono_tramp_info_create (
                                        "mono_get_tls_key",
-                                       (guint8*)mono_fast_get_tls_key,
-                                       (guint8*)mono_fast_get_tls_key_end - (guint8*)mono_fast_get_tls_key,
+                                       (guint8*)tls_imp.get_tls_thunk,
+                                       (guint8*)tls_imp.get_tls_thunk_end - (guint8*)tls_imp.get_tls_thunk,
                                        NULL,
                                        mono_arch_get_cie_program ()
                                        ),
@@ -6024,17 +5980,13 @@ mono_arch_register_lowlevel_calls (void)
                        mono_tramp_info_register (
                                mono_tramp_info_create (
                                        "mono_set_tls_key",
-                                       (guint8*)mono_fast_set_tls_key,
-                                       (guint8*)mono_fast_set_tls_key_end - (guint8*)mono_fast_set_tls_key,
+                                       (guint8*)tls_imp.set_tls_thunk,
+                                       (guint8*)tls_imp.set_tls_thunk_end - (guint8*)tls_imp.set_tls_thunk,
                                        NULL,
                                        mono_arch_get_cie_program ()
                                        ),
                                NULL
                                );
-               } else {
-                       g_warning ("No fast tls on device. Using fallbacks.");
-                       mono_register_jit_icall (mono_fallback_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
-                       mono_register_jit_icall (mono_fallback_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
                }
        }
 #endif
@@ -6585,15 +6537,12 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                }
        }
 
-       if (cfg->arch.seq_point_read_var) {
-               MonoInst *read_ins = cfg->arch.seq_point_read_var;
+       if (cfg->arch.seq_point_ss_method_var) {
                MonoInst *ss_method_ins = cfg->arch.seq_point_ss_method_var;
                MonoInst *bp_method_ins = cfg->arch.seq_point_bp_method_var;
 #ifdef USE_JUMP_TABLES
                gpointer *jte;
 #endif
-               g_assert (read_ins->opcode == OP_REGOFFSET);
-               g_assert (arm_is_imm12 (read_ins->inst_offset));
                g_assert (ss_method_ins->opcode == OP_REGOFFSET);
                g_assert (arm_is_imm12 (ss_method_ins->inst_offset));
                g_assert (bp_method_ins->opcode == OP_REGOFFSET);
@@ -6601,26 +6550,21 @@ mono_arch_emit_prolog (MonoCompile *cfg)
 
 #ifdef USE_JUMP_TABLES
                jte = mono_jumptable_add_entries (3);
-               jte [0] = (gpointer)&ss_trigger_var;
-               jte [1] = single_step_tramp;
-               jte [2] = breakpoint_tramp;
+               jte [0] = &single_step_tramp;
+               jte [1] = breakpoint_tramp;
                code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_LR);
 #else
                ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
                ARM_B (code, 2);
-               *(volatile int **)code = &ss_trigger_var;
-               code += 4;
-               *(gpointer*)code = single_step_tramp;
+               *(gpointer*)code = &single_step_tramp;
                code += 4;
                *(gpointer*)code = breakpoint_tramp;
                code += 4;
 #endif
 
                ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 0);
-               ARM_STR_IMM (code, ARMREG_IP, read_ins->inst_basereg, read_ins->inst_offset);
-               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 4);
                ARM_STR_IMM (code, ARMREG_IP, ss_method_ins->inst_basereg, ss_method_ins->inst_offset);
-               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 8);
+               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 4);
                ARM_STR_IMM (code, ARMREG_IP, bp_method_ins->inst_basereg, bp_method_ins->inst_offset);
        }
 
@@ -7491,7 +7435,7 @@ mono_arch_start_single_stepping (void)
        if (ss_trigger_page)
                mono_mprotect (ss_trigger_page, mono_pagesize (), 0);
        else
-               ss_trigger_var = 1;
+               single_step_tramp = mini_get_single_step_trampoline ();
 }
        
 /*
@@ -7505,7 +7449,7 @@ mono_arch_stop_single_stepping (void)
        if (ss_trigger_page)
                mono_mprotect (ss_trigger_page, mono_pagesize (), MONO_MMAP_READ);
        else
-               ss_trigger_var = 0;
+               single_step_tramp = NULL;
 }
 
 #if __APPLE__