/*
* 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;
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)
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);
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);
clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY;
#endif
- mono_loader_lock ();
+ mono_marshal_lock ();
if (!enter_method) {
MonoMethodDesc *desc;
mono_method_desc_free (desc);
}
- mono_loader_unlock ();
+ mono_marshal_unlock ();
#ifndef DISABLE_JIT
/* Push this or the type object */
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;
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
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;
* 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)) {
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;
}