*
* type metadata format:
* type: TYPE_METADATA
- * exinfo: one of: TYPE_END_LOAD, TYPE_END_UNLOAD (optional for TYPE_THREAD and TYPE_DOMAIN)
+ * exinfo: one of: TYPE_END_LOAD, TYPE_END_UNLOAD (optional for TYPE_THREAD and TYPE_DOMAIN,
+ * doesn't occur for TYPE_CLASS)
* [mtype: byte] metadata type, one of: TYPE_CLASS, TYPE_IMAGE, TYPE_ASSEMBLY, TYPE_DOMAIN,
* TYPE_THREAD, TYPE_CONTEXT
* [pointer: sleb128] pointer of the metadata type depending on mtype
* exclusive lock, and we need those to arrive with a reasonably
* consistent frequency so that readers don't have to queue up too many
* events between sync points.
+ *
+ * The lock does not support recursion.
*/
static volatile gint32 buffer_lock_state;
static volatile gint32 buffer_lock_exclusive_intent;
-// Can be used recursively.
static void
buffer_lock (void)
{
InterlockedDecrement (&buffer_lock_state);
}
-// Cannot be used recursively.
static void
buffer_lock_excl (void)
{
g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
}
+// The reader lock must be held.
static void
register_method_local (MonoMethod *method, MonoJitInfo *ji)
{
info->ji = ji;
info->time = current_time ();
- buffer_lock ();
-
GPtrArray *arr = thread->methods ? thread->methods : (thread->methods = g_ptr_array_new ());
g_ptr_array_add (arr, info);
-
- buffer_unlock ();
}
}
g_free (name);
}
-static void
-class_unloaded (MonoProfiler *prof, MonoClass *klass)
-{
- char *name;
-
- if (InterlockedRead (&runtime_inited))
- name = mono_type_get_name (mono_class_get_type (klass));
- else
- name = type_name (klass);
-
- int nlen = strlen (name) + 1;
- MonoImage *image = mono_class_get_image (klass);
-
- ENTER_LOG (&class_unloads_ctr, logbuffer,
- EVENT_SIZE /* event */ +
- BYTE_SIZE /* type */ +
- LEB128_SIZE /* klass */ +
- LEB128_SIZE /* image */ +
- nlen /* name */
- );
-
- emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
- emit_byte (logbuffer, TYPE_CLASS);
- emit_ptr (logbuffer, klass);
- emit_ptr (logbuffer, image);
- memcpy (logbuffer->cursor, name, nlen);
- logbuffer->cursor += nlen;
-
- EXIT_LOG;
-
- if (runtime_inited)
- mono_free (name);
- else
- g_free (name);
-}
-
static void process_method_enter_coverage (MonoProfiler *prof, MonoMethod *method);
static void
if (result != MONO_PROFILE_OK)
return;
+ buffer_lock ();
+
register_method_local (method, ji);
+
+ buffer_unlock ();
}
static void
if (config.effective_mask & PROFLOG_CLASS_EVENTS) {
events |= MONO_PROFILE_CLASS_EVENTS;
- mono_profiler_install_class (NULL, class_loaded, class_unloaded, NULL);
+ mono_profiler_install_class (NULL, class_loaded, NULL, NULL);
}
if (config.effective_mask & PROFLOG_JIT_COMPILATION_EVENTS) {