Implement a fast version of mono_get_lmf_addr () on ARM by inlining the call to pthre...
authorZoltan Varga <vargaz@gmail.com>
Fri, 1 Mar 2013 04:01:19 +0000 (05:01 +0100)
committerZoltan Varga <vargaz@gmail.com>
Fri, 1 Mar 2013 04:01:19 +0000 (05:01 +0100)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini-arm.c
mono/mini/mini.c
mono/mini/patch-info.h

index 1c03981310d53086262414a30bd3831fba6bf25a..61af478f6f248087fb9b12205e35aebd7bbd3508 100644 (file)
@@ -4437,6 +4437,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                encode_value (get_image_index (acfg, patch_info->data.image), p, &p);
                break;
        case MONO_PATCH_INFO_MSCORLIB_GOT_ADDR:
+       case MONO_PATCH_INFO_JIT_TLS_ID:
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
                break;
@@ -8179,6 +8180,10 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
                ji->type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
                get_got_offset (acfg, ji);
+
+               ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
+               ji->type = MONO_PATCH_INFO_JIT_TLS_ID;
+               get_got_offset (acfg, ji);
        }
 
        TV_GETTIME (atv);
index cd164ebd71d6e8eb0ac030d318215342ef3a68fa..e08d90fbde52d6ff4a8693770d40fe015c52690f 100644 (file)
@@ -2885,6 +2885,7 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
+       case MONO_PATCH_INFO_JIT_TLS_ID:
                break;
        case MONO_PATCH_INFO_RGCTX_FETCH: {
                gboolean res;
index ec1d943550dc4709ecf246f9ced46a72ea25c3b8..eabff5c1c5c98ef4aa4d5404ed65e2ea73374ee2 100644 (file)
@@ -385,7 +385,7 @@ emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
        if (lmf_addr_tls_offset != -1) {
                get_lmf_fast = TRUE;
 
-               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
+               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
                                                         (gpointer)"__aeabi_read_tp");
                code = emit_call_seq (cfg, code);
 
@@ -393,9 +393,38 @@ emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
                get_lmf_fast = TRUE;
        }
 #endif
+
+#ifdef TARGET_IOS
+       if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+               int lmf_offset;
+
+               /* Inline mono_get_lmf_addr () */
+               /* jit_tls = pthread_getspecific (mono_jit_tls_id); lmf_addr = &jit_tls->lmf; */
+
+               /* Load mono_jit_tls_id */
+               /* OP_AOTCONST */
+               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_TLS_ID, NULL);
+               ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0);
+               ARM_B (code, 0);
+               *(gpointer*)code = NULL;
+               code += 4;
+               ARM_LDR_REG_REG (code, ARMREG_R0, ARMREG_PC, ARMREG_R0);
+               /* call pthread_getspecific () */
+               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
+                                                        (gpointer)"pthread_getspecific");
+               code = emit_call_seq (cfg, code);
+               /* lmf_addr = &jit_tls->lmf */
+               lmf_offset = G_STRUCT_OFFSET (MonoJitTlsData, lmf);
+               g_assert (arm_is_imm8 (lmf_offset));
+               ARM_ADD_REG_IMM (code, ARMREG_R0, ARMREG_R0, lmf_offset, 0);
+
+               get_lmf_fast = TRUE;
+       }
+#endif
+
        if (!get_lmf_fast) {
                mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
-                                                                (gpointer)"mono_get_lmf_addr");
+                                                        (gpointer)"mono_get_lmf_addr");
                code = emit_call_seq (cfg, code);
        }
        /* we build the MonoLMF structure on the stack - see mini-arm.h */
index dfdbc8b94007b194a27927e59d155de849152eff..214a5c285519875f55dd7750c3eb244be4942f5e 100644 (file)
@@ -3362,6 +3362,10 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                target = mono_domain_alloc0 (domain, sizeof (gpointer));
                break;
        }
+       case MONO_PATCH_INFO_JIT_TLS_ID: {
+               target = (gpointer)mono_jit_tls_id;
+               break;
+       }
        default:
                g_assert_not_reached ();
        }
@@ -7099,7 +7103,10 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_object_isinst_with_cache, "mono_object_isinst_with_cache", "object object ptr ptr", FALSE);
 
        register_icall (mono_debugger_agent_user_break, "mono_debugger_agent_user_break", "void", FALSE);
+#endif
 
+#ifdef TARGET_IOS
+       register_icall (pthread_getspecific, "pthread_getspecific", NULL, TRUE);
 #endif
 
        mono_generic_sharing_init ();
index 53800be31bb64b78d7635fdb8f7c5e931ae1325d..b7fd39d808133ebd4cdfb8f93f330c698b02bde9 100644 (file)
@@ -44,4 +44,6 @@ PATCH_INFO(GC_CARD_TABLE_ADDR, "gc_card_table_addr")
 PATCH_INFO(CASTCLASS_CACHE, "castclass_cache")
 PATCH_INFO(SIGNATURE, "signature")
 PATCH_INFO(GSHAREDVT_CALL, "gsharedvt_call")
+PATCH_INFO(JIT_TLS_ID, "jit_tls_id")
 PATCH_INFO(NONE, "none")
+