From 9862fc93c30c2b0da3d877da69a2964d81020033 Mon Sep 17 00:00:00 2001 From: joncham Date: Wed, 12 Sep 2007 18:24:40 +0000 Subject: [PATCH] 2007-09-12 Jonathan Chambers * mini-x86.c (mono_arch_get_delegate_invoke_impl): Implement static case. Cache delegates in architecture specific code, based on number of parameters. * mini-amd64.c (mono_arch_get_delegate_invoke_impl): Cache delegates in architecture specific code, based on number of parameters. * mini-trampolines.c (mono_delegate_trampoline): Architecture specific caching happen in architecture specific code now. Code is contributed under MIT/X11 license. 2007-09-12 Jonathan Chambers * domain-internals.h, domain.c : Remove delegate_invoke_impl_with_target_hash and delegate_invoke_impl_no_target_hash from _MonoDomain struct. Code is contributed under MIT/X11 license. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mono@85697 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- mono/metadata/ChangeLog | 7 +++ mono/metadata/domain-internals.h | 2 - mono/metadata/domain.c | 9 +--- mono/mini/ChangeLog | 14 ++++++ mono/mini/mini-amd64.c | 36 ++++++++++++--- mono/mini/mini-trampolines.c | 24 ---------- mono/mini/mini-x86.c | 97 +++++++++++++++++++++++++--------------- 7 files changed, 113 insertions(+), 76 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 26a23797b..7da0d99c1 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,10 @@ +2007-09-12 Jonathan Chambers + + * domain-internals.h, domain.c : Remove delegate_invoke_impl_with_target_hash + and delegate_invoke_impl_no_target_hash from _MonoDomain struct. + + Code is contributed under MIT/X11 license. + 2007-09-10 Massimiliano Mantione * domain.c, object.c, mono-config.c, object-internals.h: Fixed #82416. diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index ca9febde9..04019e03c 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -172,8 +172,6 @@ struct _MonoDomain { GHashTable *jump_trampoline_hash; GHashTable *jit_trampoline_hash; GHashTable *delegate_trampoline_hash; - GHashTable *delegate_invoke_impl_with_target_hash; - GHashTable *delegate_invoke_impl_no_target_hash; /* * This must be a GHashTable, since these objects can't be finalized * if the hashtable contains a GC visible reference to them. diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index 5314080c6..b9ef62378 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -1748,14 +1748,7 @@ mono_domain_free (MonoDomain *domain, gboolean force) domain->jit_trampoline_hash = NULL; g_hash_table_destroy (domain->delegate_trampoline_hash); domain->delegate_trampoline_hash = NULL; - if (domain->delegate_invoke_impl_with_target_hash) { - g_hash_table_destroy (domain->delegate_invoke_impl_with_target_hash); - domain->delegate_invoke_impl_with_target_hash = NULL; - } - if (domain->delegate_invoke_impl_no_target_hash) { - g_hash_table_destroy (domain->delegate_invoke_impl_no_target_hash); - domain->delegate_invoke_impl_no_target_hash = NULL; - } + DeleteCriticalSection (&domain->assemblies_lock); DeleteCriticalSection (&domain->lock); domain->setup = NULL; diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index ee1d8b4b7..88a12a310 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,5 +1,19 @@ 2007-09-12 Jonathan Chambers + * mini-x86.c (mono_arch_get_delegate_invoke_impl): Implement + static case. Cache delegates in architecture specific code, + based on number of parameters. + + * mini-amd64.c (mono_arch_get_delegate_invoke_impl): Cache delegates + in architecture specific code, based on number of parameters. + + * mini-trampolines.c (mono_delegate_trampoline): Architecture specific + caching happen in architecture specific code now. + + Code is contributed under MIT/X11 license. + +2007-09-12 Jonathan Chambers + * mini.h, mini.c, mini-x86.c, mini-amd64.c, mini-hppa.c, mini-mips.c, mini-s390x.c, mini-arm.c, mini-ia64.c, mini-sparc.c, mini-ppc.c, mini-alpha.c, mini-s390.c: Add mono_arch_init and mono_arch_cleanup methods. diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index ee54055b0..68368bea3 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -5310,21 +5310,30 @@ mono_arch_get_this_arg_from_call (MonoMethodSignature *sig, gssize *regs, guint8 return (gpointer)regs [AMD64_RDI]; } +#define MAX_ARCH_DELEGATE_PARAMS 10 + gpointer mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) { guint8 *code, *start; - MonoDomain *domain = mono_domain_get (); int i; + if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS) + return NULL; + /* FIXME: Support more cases */ if (MONO_TYPE_ISSTRUCT (sig->ret)) return NULL; if (has_target) { - mono_domain_lock (domain); - start = code = mono_code_manager_reserve (domain->code_mp, 64); - mono_domain_unlock (domain); + static guint8* cached = NULL; + mono_mini_arch_lock (); + if (cached) { + mono_mini_arch_unlock (); + return cached; + } + + start = code = mono_global_codeman_reserve (64); /* Replace the this argument with the target */ amd64_mov_reg_reg (code, AMD64_RAX, AMD64_RDI, 8); @@ -5332,16 +5341,25 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe amd64_jump_membase (code, AMD64_RAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); g_assert ((code - start) < 64); + + cached = start; + mono_mini_arch_unlock (); } else { + static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL}; for (i = 0; i < sig->param_count; ++i) if (!mono_is_regsize_var (sig->params [i])) return NULL; if (sig->param_count > 4) return NULL; - mono_domain_lock (domain); - start = code = mono_code_manager_reserve (domain->code_mp, 64); - mono_domain_unlock (domain); + mono_mini_arch_lock (); + code = cache [sig->param_count]; + if (code) { + mono_mini_arch_unlock (); + return code; + } + + start = code = mono_global_codeman_reserve (64); if (sig->param_count == 0) { amd64_jump_membase (code, AMD64_RDI, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); @@ -5354,6 +5372,10 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe amd64_jump_membase (code, AMD64_RAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); } g_assert ((code - start) < 64); + + cache [sig->param_count] = start; + + mono_mini_arch_unlock (); } return start; diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index 7ec5dc352..5bc561a3f 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -266,33 +266,9 @@ mono_delegate_trampoline (gssize *regs, guint8 *code, MonoClass *klass, guint8* multicast = ((MonoMulticastDelegate*)delegate)->prev != NULL; if (!multicast) { - guint8* code; - GHashTable *cache; - - mono_domain_lock (domain); - if (delegate->target != NULL) { - if (!domain->delegate_invoke_impl_with_target_hash) - domain->delegate_invoke_impl_with_target_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); - cache = domain->delegate_invoke_impl_with_target_hash; - } else { - if (!domain->delegate_invoke_impl_no_target_hash) - domain->delegate_invoke_impl_no_target_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); - cache = domain->delegate_invoke_impl_no_target_hash; - } - code = g_hash_table_lookup (cache, mono_method_signature (invoke)); - mono_domain_unlock (domain); - if (code) { - delegate->invoke_impl = code; - return code; - } - code = mono_arch_get_delegate_invoke_impl (mono_method_signature (invoke), delegate->target != NULL); if (code) { - mono_domain_lock (domain); - g_hash_table_insert (cache, mono_method_signature (invoke), code); - mono_domain_unlock (domain); - delegate->invoke_impl = code; return code; } diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index ac5f3b487..97d1e8a2a 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -4521,11 +4521,15 @@ mono_arch_get_this_arg_from_call (MonoMethodSignature *sig, gssize *regs, guint8 return res; } +#define MAX_ARCH_DELEGATE_PARAMS 10 + gpointer mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) { guint8 *code, *start; - MonoDomain *domain = mono_domain_get (); + + if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS) + return NULL; /* FIXME: Support more cases */ if (MONO_TYPE_ISSTRUCT (sig->ret)) @@ -4538,9 +4542,14 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe */ if (has_target) { - mono_domain_lock (domain); - start = code = mono_code_manager_reserve (domain->code_mp, 64); - mono_domain_unlock (domain); + static guint8* cached = NULL; + mono_mini_arch_lock (); + if (cached) { + mono_mini_arch_unlock (); + return cached; + } + + start = code = mono_global_codeman_reserve (64); /* Replace the this argument with the target */ x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4); @@ -4549,43 +4558,61 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe x86_jump_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); g_assert ((code - start) < 64); + + cached = start; + + mono_mini_arch_unlock (); } else { - if (sig->param_count == 0) { - mono_domain_lock (domain); - start = code = mono_code_manager_reserve (domain->code_mp, 32 + (sig->param_count * 8)); - mono_domain_unlock (domain); - - x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4); - x86_jump_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); - } else { - /* - * The code below does not work in the presence of exceptions, since it - * creates a new frame. - */ - start = NULL; -#if 0 - for (i = 0; i < sig->param_count; ++i) - if (!mono_is_regsize_var (sig->params [i])) - return NULL; + static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL}; + int i = 0; + /* 8 for mov_reg and jump, plus 8 for each parameter */ + int code_reserve = 8 + (sig->param_count * 8); + + for (i = 0; i < sig->param_count; ++i) + if (!mono_is_regsize_var (sig->params [i])) + return NULL; + + mono_mini_arch_lock (); + code = cache [sig->param_count]; + if (code) { + mono_mini_arch_unlock (); + return code; + } - mono_domain_lock (domain); - start = code = mono_code_manager_reserve (domain->code_mp, 32 + (sig->param_count * 8)); - mono_domain_unlock (domain); + /* + * The stack contains: + * + * + * + * + * and we need: + * + * + * + * without unbalancing the stack. + * So move each arg up a spot in the stack (overwriting un-needed 'this' arg) + * and leaving original spot of first arg as placeholder in stack so + * when callee pops stack everything works. + */ - /* Load this == delegate */ - x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4); + start = code = mono_global_codeman_reserve (code_reserve); - /* Push arguments in opposite order, taking changes in ESP into account */ - for (i = 0; i < sig->param_count; ++i) - x86_push_membase (code, X86_ESP, 4 + (sig->param_count * 4)); + /* store delegate for access to method_ptr */ + x86_mov_reg_membase (code, X86_ECX, X86_ESP, 4, 4); - /* Call the delegate */ - x86_call_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); - if (sig->param_count > 0) - x86_alu_reg_imm (code, X86_ADD, X86_ESP, sig->param_count * 4); - x86_ret (code); -#endif + /* move args up */ + for (i = 0; i < sig->param_count; ++i) { + x86_mov_reg_membase (code, X86_EAX, X86_ESP, (i+2)*4, 4); + x86_mov_membase_reg (code, X86_ESP, (i+1)*4, X86_EAX, 4); } + + x86_jump_membase (code, X86_ECX, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); + + g_assert ((code - start) < code_reserve); + + cache [sig->param_count] = start; + + mono_mini_arch_unlock (); } return start; -- 2.11.4.GIT