X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=2b66637c2bf6c5368ed6039407034fd3a918e68b;hb=d6cdd9715eff6eeac53c9d0970a90e49b7c80edd;hp=c664d129b41a7f26f4bc1b08814124e554214c16;hpb=02bd4773cb60015de2fbddd0a4759924ead9e2a2;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index c664d129b41..2b66637c2bf 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -164,7 +164,14 @@ register_icall (gpointer func, const char *name, const char *sigstr, gboolean sa static MonoMethodSignature* signature_dup (MonoImage *image, MonoMethodSignature *sig) { - return mono_metadata_signature_dup_full (image, sig); + MonoMethodSignature *res; + int sigsize; + + res = mono_metadata_signature_alloc (image, sig->param_count); + sigsize = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *); + memcpy (res, sig, sigsize); + + return res; } MonoMethodSignature* @@ -564,10 +571,10 @@ mono_array_to_lparray (MonoArray *array) case MONO_TYPE_R4: case MONO_TYPE_R8: case MONO_TYPE_VALUETYPE: + case MONO_TYPE_PTR: /* nothing to do */ break; case MONO_TYPE_GENERICINST: - case MONO_TYPE_PTR: case MONO_TYPE_OBJECT: case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: @@ -2276,15 +2283,13 @@ mono_marshal_need_free (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec * Return the hash table pointed to by VAR, lazily creating it if neccesary. */ static GHashTable* -get_cache_full (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func, - GDestroyNotify key_destroy_func, - GDestroyNotify value_destroy_func) +get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func) { if (!(*var)) { mono_marshal_lock (); if (!(*var)) { GHashTable *cache = - g_hash_table_new_full (hash_func, equal_func, key_destroy_func, value_destroy_func); + g_hash_table_new (hash_func, equal_func); mono_memory_barrier (); *var = cache; } @@ -2293,12 +2298,6 @@ get_cache_full (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func, return *var; } -static GHashTable* -get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func) -{ - return get_cache_full (var, hash_func, equal_func, NULL, NULL); -} - GHashTable* mono_marshal_get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func) { @@ -2423,14 +2422,25 @@ MonoMethod * mono_marshal_method_from_wrapper (MonoMethod *wrapper) { gpointer res; + int wrapper_type = wrapper->wrapper_type; - if (wrapper->wrapper_type == MONO_WRAPPER_NONE || wrapper->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) + if (wrapper_type == MONO_WRAPPER_NONE || wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) return wrapper; - res = mono_method_get_wrapper_data (wrapper, 1); - if (res == NULL) - return wrapper; - return res; + switch (wrapper_type) { + case MONO_WRAPPER_REMOTING_INVOKE: + case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: + case MONO_WRAPPER_XDOMAIN_INVOKE: + case MONO_WRAPPER_SYNCHRONIZED: + case MONO_WRAPPER_MANAGED_TO_NATIVE: + case MONO_WRAPPER_RUNTIME_INVOKE: + res = mono_method_get_wrapper_data (wrapper, 1); + if (res == NULL) + return wrapper; + return res; + default: + return NULL; + } } /* @@ -3755,6 +3765,7 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) MonoMethod *target_method = NULL; MonoClass *target_class = NULL; gboolean callvirt = FALSE; + gboolean closed_over_null = FALSE; /* * If the delegate target is null, and the target method is not static, a virtual @@ -3781,6 +3792,9 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) sig = mono_signature_no_pinvoke (method); + if (callvirt) + closed_over_null = sig->param_count == mono_method_signature (del->method)->param_count; + if (callvirt) { /* We need to cache the signature+method pair */ mono_marshal_lock (); @@ -3878,11 +3892,18 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) mono_mb_patch_branch (mb, pos0); if (callvirt) { - mono_mb_emit_ldarg (mb, 1); - mono_mb_emit_op (mb, CEE_CASTCLASS, target_class); - for (i = 1; i < sig->param_count; ++i) - mono_mb_emit_ldarg (mb, i + 1); - mono_mb_emit_op (mb, CEE_CALLVIRT, target_method); + if (!closed_over_null) { + mono_mb_emit_ldarg (mb, 1); + mono_mb_emit_op (mb, CEE_CASTCLASS, target_class); + for (i = 1; i < sig->param_count; ++i) + mono_mb_emit_ldarg (mb, i + 1); + mono_mb_emit_op (mb, CEE_CALLVIRT, target_method); + } else { + mono_mb_emit_byte (mb, CEE_LDNULL); + for (i = 0; i < sig->param_count; ++i) + mono_mb_emit_ldarg (mb, i + 1); + mono_mb_emit_op (mb, CEE_CALL, target_method); + } } else { for (i = 0; i < sig->param_count; ++i) mono_mb_emit_ldarg (mb, i + 1); @@ -4232,14 +4253,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual) /* allocate local 1 (object) exc */ mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); - /* cond set *exc to null */ - mono_mb_emit_byte (mb, CEE_LDARG_2); - mono_mb_emit_byte (mb, CEE_BRFALSE_S); - mono_mb_emit_byte (mb, 3); - mono_mb_emit_byte (mb, CEE_LDARG_2); - mono_mb_emit_byte (mb, CEE_LDNULL); - mono_mb_emit_byte (mb, CEE_STIND_REF); - emit_thread_force_interrupt_checkpoint (mb); if (virtual) { @@ -10703,7 +10716,7 @@ mono_marshal_asany (MonoObject *o, MonoMarshalNative string_encoding, int param_ case MONO_TYPE_STRING: switch (string_encoding) { case MONO_NATIVE_LPWSTR: - return mono_string_to_utf16 ((MonoString*)o); + return mono_marshal_string_to_utf16_copy ((MonoString*)o); break; case MONO_NATIVE_LPSTR: return mono_string_to_lpstr ((MonoString*)o); @@ -10802,20 +10815,6 @@ mono_marshal_free_asany (MonoObject *o, gpointer ptr, MonoMarshalNative string_e } } -/* - * free_wrapper: - * - * Wrappers of generic instances need to be dynamic, since they cannot be freed when their - * image is unloaded, since the generic instance they are based on does not belong to any - * image. This function should be the value dtor of caches holding such wrappers. - */ -static void -free_wrapper (MonoMethod *method) -{ - if (method->dynamic) - mono_free_method (method); -} - MonoMethod * mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar *name, MonoMethod *method) { @@ -10823,22 +10822,15 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar MonoMethodBuilder *mb; MonoMethod *res; int i; - GHashTable *cache; - cache = get_cache_full (&method->klass->image->generic_array_helper_cache, mono_aligned_addr_hash, NULL, NULL, (GDestroyNotify)free_wrapper); - - if ((res = mono_marshal_find_in_cache (cache, method))) - return res; - - mb = mono_mb_new (class, name, MONO_WRAPPER_MANAGED_TO_MANAGED); + mb = mono_mb_new_no_dup_name (class, name, MONO_WRAPPER_MANAGED_TO_MANAGED); mb->method->slot = -1; - mb->dynamic = TRUE; mb->method->flags = METHOD_ATTRIBUTE_PRIVATE | METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_NEW_SLOT | METHOD_ATTRIBUTE_HIDE_BY_SIG | METHOD_ATTRIBUTE_FINAL; sig = mono_method_signature (method); - csig = signature_dup (NULL, sig); + csig = signature_dup (method->klass->image, sig); csig->generic_param_count = 0; mono_mb_emit_ldarg (mb, 0); @@ -10850,7 +10842,7 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar /* We can corlib internal methods */ mb->skip_visibility = TRUE; - res = mono_mb_create_and_cache (cache, method, mb, csig, csig->param_count + 16); + res = mono_mb_create_method (mb, csig, csig->param_count + 16); mono_mb_free (mb); @@ -11156,8 +11148,6 @@ mono_marshal_free_inflated_wrappers (MonoMethod *method) g_hash_table_remove (method->klass->image->cominterop_wrapper_cache, method); if (method->klass->image->thunk_invoke_cache) g_hash_table_remove (method->klass->image->thunk_invoke_cache, method); - if (method->klass->image->generic_array_helper_cache) - g_hash_table_remove (method->klass->image->generic_array_helper_cache, method); mono_marshal_unlock (); }