#include <mono/metadata/marshal.h>
#include <mono/metadata/profiler-private.h>
#include <mono/utils/mono-time.h>
+#include <mono/utils/atomic.h>
/*
* Pull the list of opcodes
mon->data = monitor_freelist;
monitor_freelist = mon;
+#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->gc_sync_blocks--;
+#endif
}
/* LOCKING: this is called with monitor_mutex held */
new->wait_list = g_slist_remove (new->wait_list, new->wait_list->data);
}
}
- mono_gc_weak_link_remove (&new->data);
+ mono_gc_weak_link_remove (&new->data, FALSE);
new->data = monitor_freelist;
monitor_freelist = new;
}
new->owner = id;
new->nest = 1;
+ new->data = NULL;
+#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->gc_sync_blocks++;
+#endif
return new;
}
}
/* The object must be locked by someone else... */
+#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->thread_contentions++;
+#endif
/* If ms is 0 we don't block, but just fail straight away */
if (ms == 0) {
InterlockedIncrement (&mon->entry_count);
+#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->thread_queue_len++;
mono_perfcounters->thread_queue_max++;
+#endif
thread = mono_thread_internal_current ();
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
InterlockedDecrement (&mon->entry_count);
+#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->thread_queue_len--;
+#endif
if (ms != INFINITE) {
now = mono_msec_ticks ();
return NULL;
}
+#ifndef DISABLE_JIT
+
static void
emit_obj_syncp_check (MonoMethodBuilder *mb, int syncp_loc, int *obj_null_branch, int *true_locktaken_branch, int *syncp_true_false_branch,
int *thin_hash_branch, gboolean branch_on_true)
*syncp_true_false_branch = mono_mb_emit_short_branch (mb, branch_on_true ? CEE_BRTRUE_S : CEE_BRFALSE_S);
}
+#endif
+
static MonoMethod* monitor_il_fastpaths[3];
gboolean
int thread_tls_offset;
gboolean is_v4 = mono_method_signature (monitor_enter_method)->param_count == 2;
int fast_path_idx = is_v4 ? FASTPATH_ENTERV4 : FASTPATH_ENTER;
+ WrapperInfo *info;
/* The !is_v4 version is not used/tested */
g_assert (is_v4);
mb->method->flags = METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_STATIC |
METHOD_ATTRIBUTE_HIDE_BY_SIG | METHOD_ATTRIBUTE_FINAL;
+#ifndef DISABLE_JIT
tid_loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
syncp_loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
owner_loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
mono_mb_emit_byte (mb, CEE_LDARG_1);
mono_mb_emit_managed_call (mb, monitor_enter_method, NULL);
mono_mb_emit_byte (mb, CEE_RET);
+#endif
res = register_fastpath (mono_mb_create_method (mb, mono_signature_no_pinvoke (monitor_enter_method), 5), fast_path_idx);
+
+ info = mono_image_alloc0 (mono_defaults.corlib, sizeof (WrapperInfo));
+ info->subtype = is_v4 ? WRAPPER_SUBTYPE_FAST_MONITOR_ENTER_V4 : WRAPPER_SUBTYPE_FAST_MONITOR_ENTER;
+ mono_marshal_set_wrapper_info (res, info);
+
mono_mb_free (mb);
return res;
}
int obj_null_branch, has_waiting_branch, has_syncp_branch, owned_branch, nested_branch, thin_hash_branch;
int thread_tls_offset;
int syncp_loc;
+ WrapperInfo *info;
thread_tls_offset = mono_thread_get_tls_offset ();
if (thread_tls_offset == -1)
mb->method->flags = METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_STATIC |
METHOD_ATTRIBUTE_HIDE_BY_SIG | METHOD_ATTRIBUTE_FINAL;
+#ifndef DISABLE_JIT
syncp_loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, NULL, &has_syncp_branch, &thin_hash_branch, TRUE);
mono_mb_emit_byte (mb, CEE_LDARG_0);
mono_mb_emit_managed_call (mb, monitor_exit_method, NULL);
mono_mb_emit_byte (mb, CEE_RET);
+#endif
res = register_fastpath (mono_mb_create_method (mb, mono_signature_no_pinvoke (monitor_exit_method), 5), FASTPATH_EXIT);
mono_mb_free (mb);
+ info = mono_image_alloc0 (mono_defaults.corlib, sizeof (WrapperInfo));
+ info->subtype = WRAPPER_SUBTYPE_FAST_MONITOR_EXIT;
+ mono_marshal_set_wrapper_info (res, info);
+
return res;
}