From e4abb3281f6abfa1effcbfc174884a3bb63865a4 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 24 Feb 2010 04:16:26 +0000 Subject: [PATCH] 2010-02-24 Zoltan Varga * method-to-ir.c (mono_method_to_ir): Implement support for fast access to ThreadStatic variables. svn path=/trunk/mono/; revision=152328 --- mono/mini/ChangeLog | 5 +++++ mono/mini/method-to-ir.c | 30 +++++++++++++++++++++++++++--- mono/mini/mini.c | 6 ++++++ mono/mini/mini.h | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 51cd5abcedd..cabddca6560 100755 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,8 @@ +2010-02-24 Zoltan Varga + + * method-to-ir.c (mono_method_to_ir): Implement support for fast access to + ThreadStatic variables. + 2010-02-24 Zoltan Varga * debugger-agent.c (notify_thread): Skip terminated threads, since their tls diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index c74c2442738..225b488e47a 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -8132,9 +8132,33 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b * This could be later optimized to do just a couple of * memory dereferences with constant offsets. */ - MonoInst *iargs [1]; - EMIT_NEW_ICONST (cfg, iargs [0], GPOINTER_TO_UINT (addr)); - ins = mono_emit_jit_icall (cfg, mono_get_special_static_data, iargs); + if (!cfg->compile_aot && ((gsize)addr & 0x80000000) == 0 && mono_get_thread_intrinsic (cfg)) { + /* + * Fast access to TLS data + * Inline version of get_thread_static_data () in + * threads.c. + */ + guint32 offset; + int idx, static_data_reg, array_reg, dreg; + MonoInst *thread_ins; + + offset = (gsize)addr & 0x7fffffff; + idx = (offset >> 24) - 1; + + // return ((char*) thread->static_data [idx]) + (offset & 0xffffff); + thread_ins = mono_get_thread_intrinsic (cfg); + MONO_ADD_INS (cfg->cbb, thread_ins); + static_data_reg = alloc_ireg (cfg); + MONO_EMIT_NEW_LOAD_MEMBASE (cfg, static_data_reg, thread_ins->dreg, G_STRUCT_OFFSET (MonoInternalThread, static_data)); + array_reg = alloc_ireg (cfg); + MONO_EMIT_NEW_LOAD_MEMBASE (cfg, array_reg, static_data_reg, idx * sizeof (gpointer)); + dreg = alloc_ireg (cfg); + EMIT_NEW_BIALU_IMM (cfg, ins, OP_ADD_IMM, dreg, array_reg, (offset & 0xffffff)); + } else { + MonoInst *iargs [1]; + EMIT_NEW_ICONST (cfg, iargs [0], GPOINTER_TO_UINT (addr)); + ins = mono_emit_jit_icall (cfg, mono_get_special_static_data, iargs); + } } } diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 18d8fa645b5..f977b3a66c4 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -2469,6 +2469,12 @@ mono_get_domain_intrinsic (MonoCompile* cfg) return mono_create_tls_get (cfg, mono_domain_get_tls_offset ()); } +MonoInst* +mono_get_thread_intrinsic (MonoCompile* cfg) +{ + return mono_create_tls_get (cfg, mono_thread_get_tls_offset ()); +} + void mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target) { diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 09e65e5114e..0d9fe14859d 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -1481,6 +1481,7 @@ gint32 mono_get_lmf_tls_offset (void) MONO_INTERNAL; gint32 mono_get_lmf_addr_tls_offset (void) MONO_INTERNAL; MonoInst* mono_get_jit_tls_intrinsic (MonoCompile *cfg) MONO_INTERNAL; MonoInst* mono_get_domain_intrinsic (MonoCompile* cfg) MONO_INTERNAL; +MonoInst* mono_get_thread_intrinsic (MonoCompile* cfg) MONO_INTERNAL; GList *mono_varlist_insert_sorted (MonoCompile *cfg, GList *list, MonoMethodVar *mv, gboolean sort_end) MONO_INTERNAL; GList *mono_varlist_sort (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL; void mono_analyze_liveness (MonoCompile *cfg) MONO_INTERNAL; -- 2.25.1