X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=792a1dcf37eae662456b75b0dfa42202ec2db2b0;hb=30305335b8295bfb9426e95443ad2e32784c154f;hp=a6114b1b7e7d5d071e7589322ceae6dcd012a816;hpb=e946a6cdebde729e1c03ec374184254ab38da184;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index a6114b1b7e7..792a1dcf37e 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -72,11 +72,12 @@ typedef struct _MonoRemotingMethods MonoRemotingMethods; /* * This mutex protects the various marshalling related caches in MonoImage * and a few other data structures static to this file. - * Note that when this lock is held it is not possible to take other runtime - * locks like the loader lock. + * + * The marshal lock is a non-recursive complex lock that sits below the domain lock in the + * runtime locking latice. Which means it can take simple locks suck as the image lock. */ -#define mono_marshal_lock() EnterCriticalSection (&marshal_mutex) -#define mono_marshal_unlock() LeaveCriticalSection (&marshal_mutex) +#define mono_marshal_lock() mono_locks_acquire (&marshal_mutex, MarshalLock) +#define mono_marshal_unlock() mono_locks_release (&marshal_mutex, MarshalLock) static CRITICAL_SECTION marshal_mutex; static gboolean marshal_mutex_initialized; @@ -4296,7 +4297,11 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) invoke_sig = static_sig; if (static_method_with_first_arg_bound) - name = mono_signature_to_name (invoke_sig, "invoke_bound_"); + name = mono_signature_to_name (invoke_sig, "invoke_bound"); + else if (closed_over_null) + name = mono_signature_to_name (invoke_sig, "invoke_closed_over_null"); + else if (callvirt) + name = mono_signature_to_name (invoke_sig, "invoke_callvirt"); else name = mono_signature_to_name (sig, "invoke"); if (ctx) @@ -5209,14 +5214,14 @@ mono_marshal_get_runtime_invoke_dynamic (void) mono_mb_emit_byte (mb, CEE_RET); #endif /* DISABLE_JIT */ - mono_loader_lock (); + mono_marshal_lock (); /* double-checked locking */ if (!method) { method = mono_mb_create_method (mb, csig, 16); info = mono_wrapper_info_create (method, WRAPPER_SUBTYPE_RUNTIME_INVOKE_DYNAMIC); mono_marshal_set_wrapper_info (method, info); } - mono_loader_unlock (); + mono_marshal_unlock (); mono_mb_free (mb); @@ -9655,8 +9660,8 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) sig = mono_method_signature (method); mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED); -#ifndef DISABLE_JIT param_count = sig->param_count + sig->hasthis; +#ifndef DISABLE_JIT for (i = 0; i < param_count; i++) mono_mb_emit_ldarg (mb, i); @@ -10462,7 +10467,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY; #endif - mono_loader_lock (); + mono_marshal_lock (); if (!enter_method) { MonoMethodDesc *desc; @@ -10483,7 +10488,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) mono_method_desc_free (desc); } - mono_loader_unlock (); + mono_marshal_unlock (); #ifndef DISABLE_JIT /* Push this or the type object */ @@ -11799,7 +11804,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rty layout = (klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK); - if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT) { + if (type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR) { + return sizeof (gpointer); + } else if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT) { gchar *msg; MonoException *exc; @@ -12212,12 +12219,8 @@ mono_marshal_load_type_info (MonoClass* klass) if (!klass->inited) mono_class_init (klass); - mono_loader_lock (); - - if (klass->marshal_info) { - mono_loader_unlock (); + if (klass->marshal_info) return klass->marshal_info; - } /* * This function can recursively call itself, so we keep the list of classes which are @@ -12293,7 +12296,7 @@ mono_marshal_load_type_info (MonoClass* klass) case TYPE_ATTRIBUTE_EXPLICIT_LAYOUT: size = mono_marshal_type_size (field->type, info->fields [j].mspec, &align, TRUE, klass->unicode); - min_align = packing; + min_align = MAX (align, min_align); info->fields [j].offset = field->offset - sizeof (MonoObject); info->native_size = MAX (info->native_size, info->fields [j].offset + size); break; @@ -12307,9 +12310,12 @@ mono_marshal_load_type_info (MonoClass* klass) * If the provided Size is equal or larger than the calculated size, and there * was no Pack attribute, we set min_align to 1 to avoid native_size being increased */ - if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) + if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) { if (native_size && native_size == info->native_size && klass->packing_size == 0) min_align = 1; + else + min_align = MIN (min_align, packing); + } } if (info->native_size & (min_align - 1)) { @@ -12332,12 +12338,13 @@ mono_marshal_load_type_info (MonoClass* klass) loads_list = g_slist_remove (loads_list, klass); mono_native_tls_set_value (load_type_info_tls_id, loads_list); - /*We do double-checking locking on marshal_info */ - mono_memory_barrier (); - - klass->marshal_info = info; - - mono_loader_unlock (); + mono_marshal_lock (); + if (!klass->marshal_info) { + /*We do double-checking locking on marshal_info */ + mono_memory_barrier (); + klass->marshal_info = info; + } + mono_marshal_unlock (); return klass->marshal_info; }