From e8f48de9bb3dfc4a038e0c61b5cd1542e8fbfb93 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Fri, 30 Jan 2015 15:26:03 +0000 Subject: [PATCH 1/2] [runtime] Renamed SignatureMethodPair to SignaturePointerPair. Changed field MonoMethod* method to gpointer pointer. This change was done because we need in some cases to use a signature pointer pair. --- mono/metadata/marshal.c | 44 +++++++++++++++--------------- mono/metadata/metadata-internals.h | 4 +-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 91fee5e4885e5..e3d17467f8d50 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -2993,34 +2993,34 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method) typedef struct { MonoMethodSignature *sig; - MonoMethod *method; -} SignatureMethodPair; + gpointer pointer; +} SignaturePointerPair; static guint -signature_method_pair_hash (gconstpointer data) +signature_pointer_pair_hash (gconstpointer data) { - SignatureMethodPair *pair = (SignatureMethodPair*)data; + SignaturePointerPair *pair = (SignaturePointerPair*)data; - return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->method); + return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->pointer); } static gboolean -signature_method_pair_equal (SignatureMethodPair *pair1, SignatureMethodPair *pair2) +signature_pointer_pair_equal (gconstpointer data1, gconstpointer data2) { - return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->method == pair2->method); + SignaturePointerPair *pair1 = (SignaturePointerPair*) data1, *pair2 = (SignaturePointerPair*) data2; + return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->pointer == pair2->pointer); } static gboolean -signature_method_pair_matches_method (gpointer key, gpointer value, gpointer user_data) +signature_pointer_pair_matches_pointer (gpointer key, gpointer value, gpointer user_data) { - SignatureMethodPair *pair = (SignatureMethodPair*)key; - MonoMethod *method = (MonoMethod*)user_data; + SignaturePointerPair *pair = (SignaturePointerPair*)key; - return pair->method == method; + return pair->pointer == user_data; } static void -free_signature_method_pair (SignatureMethodPair *pair) +free_signature_pointer_pair (SignaturePointerPair *pair) { g_free (pair); } @@ -3034,8 +3034,8 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt MonoMethod *res; GHashTable *cache; gpointer cache_key = NULL; - SignatureMethodPair key; - SignatureMethodPair *new_key; + SignaturePointerPair key; + SignaturePointerPair *new_key; int local_prev, local_target; int pos0; char *name; @@ -3124,10 +3124,10 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt /* We need to cache the signature+method pair */ mono_marshal_lock (); if (!*cache_ptr) - *cache_ptr = g_hash_table_new_full (signature_method_pair_hash, (GEqualFunc)signature_method_pair_equal, (GDestroyNotify)free_signature_method_pair, NULL); + *cache_ptr = g_hash_table_new_full (signature_pointer_pair_hash, (GEqualFunc)signature_pointer_pair_equal, (GDestroyNotify)free_signature_pointer_pair, NULL); cache = *cache_ptr; key.sig = invoke_sig; - key.method = target_method; + key.pointer = target_method; res = g_hash_table_lookup (cache, &key); mono_marshal_unlock (); if (res) @@ -3278,7 +3278,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt def = mono_mb_create_and_cache (cache, cache_key, mb, sig, sig->param_count + 16); res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); } else if (callvirt) { - new_key = g_new0 (SignatureMethodPair, 1); + new_key = g_new0 (SignaturePointerPair, 1); *new_key = key; info = mono_wrapper_info_create (mb, subtype); @@ -11127,7 +11127,7 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) if (image->runtime_invoke_direct_cache) g_hash_table_remove (image->runtime_invoke_direct_cache, method); if (image->delegate_abstract_invoke_cache) - g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_method_pair_matches_method, method); + g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_pointer_pair_matches_pointer, method); // FIXME: Need to clear the caches in other images as well if (image->delegate_bound_static_invoke_cache) g_hash_table_remove (image->delegate_bound_static_invoke_cache, mono_method_signature (method)); @@ -11137,9 +11137,9 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) } static gboolean -signature_method_pair_matches_signature (gpointer key, gpointer value, gpointer user_data) +signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data) { - SignatureMethodPair *pair = (SignatureMethodPair*)key; + SignaturePointerPair *pair = (SignaturePointerPair*)key; MonoMethodSignature *sig = (MonoMethodSignature*)user_data; return mono_metadata_signature_equal (pair->sig, sig); @@ -11183,11 +11183,11 @@ mono_marshal_free_inflated_wrappers (MonoMethod *method) g_hash_table_remove (method->klass->image->runtime_invoke_vtype_cache, sig); /* - * indexed by SignatureMethodPair + * indexed by SignaturePointerPair */ if (sig && method->klass->image->delegate_abstract_invoke_cache) g_hash_table_foreach_remove (method->klass->image->delegate_abstract_invoke_cache, - signature_method_pair_matches_signature, (gpointer)sig); + signature_pointer_pair_matches_signature, (gpointer)sig); /* * indexed by MonoMethod pointers diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index d297e7aaf919e..db87ad7e3fce7 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -261,12 +261,12 @@ struct _MonoImage { GHashTable *runtime_invoke_vtype_cache; /* - * indexed by SignatureMethodPair + * indexed by SignaturePointerPair */ GHashTable *delegate_abstract_invoke_cache; /* - * indexed by SignatureMethodPair + * indexed by SignaturePointerPair */ GHashTable *delegate_bound_static_invoke_cache; /* From 09c48bc964e7c9e8158bc4d4eeb370be888443bf Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Fri, 30 Jan 2015 15:40:33 +0000 Subject: [PATCH 2/2] [runtime] Added native_func_wrapper_cache. mono_marshal_get_native_func_wrapper now uses native_func_wrapper_cache indexed by SignaturePointerPair, Using SignaturePointerPair index instead of MonoMethod index avoids problems when one native function needs multiple wrappers. e.g: when the managed code creates delegates for function pointers with parameters that require different marshallings. This fixes bug 26127. --- mono/metadata/image.c | 1 + mono/metadata/marshal.c | 18 ++++++++++++++---- mono/metadata/metadata-internals.h | 6 ++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/mono/metadata/image.c b/mono/metadata/image.c index c7c0756dc7161..33c389cb4bfb3 100644 --- a/mono/metadata/image.c +++ b/mono/metadata/image.c @@ -1618,6 +1618,7 @@ mono_image_close_except_pools (MonoImage *image) } free_hash (image->native_wrapper_cache); + free_hash (image->native_func_wrapper_cache); free_hash (image->managed_wrapper_cache); free_hash (image->delegate_begin_invoke_cache); free_hash (image->delegate_end_invoke_cache); diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index e3d17467f8d50..905ae039452a8 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -7368,13 +7368,18 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig { MonoMethodSignature *csig; + SignaturePointerPair key, *new_key; MonoMethodBuilder *mb; MonoMethod *res; GHashTable *cache; + gboolean found; char *name; - cache = get_cache (&image->native_wrapper_cache, mono_aligned_addr_hash, NULL); - if ((res = mono_marshal_find_in_cache (cache, func))) + key.sig = sig; + key.pointer = func; + + cache = get_cache (&image->native_func_wrapper_cache, signature_pointer_pair_hash, signature_pointer_pair_equal); + if ((res = mono_marshal_find_in_cache (cache, &key))) return res; name = g_strdup_printf ("wrapper_native_%p", func); @@ -7387,8 +7392,13 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig csig = signature_dup (image, sig); csig->pinvoke = 0; - res = mono_mb_create_and_cache (cache, func, - mb, csig, csig->param_count + 16); + + new_key = g_new (SignaturePointerPair,1); + *new_key = key; + res = mono_mb_create_and_cache_full (cache, new_key, mb, csig, csig->param_count + 16, NULL, &found); + if (found) + g_free (new_key); + mono_mb_free (mb); mono_marshal_set_wrapper_info (res, NULL); diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index db87ad7e3fce7..14eb80cd79340 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -264,11 +264,9 @@ struct _MonoImage { * indexed by SignaturePointerPair */ GHashTable *delegate_abstract_invoke_cache; - - /* - * indexed by SignaturePointerPair - */ GHashTable *delegate_bound_static_invoke_cache; + GHashTable *native_func_wrapper_cache; + /* * indexed by MonoMethod pointers */