[mcs] Accept and ignore command line args supported by csc ..
[mono.git] / mono / profiler / proflog.c
index 465aab3149b4ec45f48319b7031696afb7ed53e8..9120ae06916850b4154f96828b7bb34757b40a41 100644 (file)
@@ -23,7 +23,7 @@
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-membar.h>
 #include <mono/utils/mono-counters.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
 #include <mono/utils/mono-conc-hashtable.h>
 #include <mono/utils/lock-free-queue.h>
 #include <stdlib.h>
@@ -91,6 +91,12 @@ static int read_perf_mmap (MonoProfiler* prof, int cpu);
 #endif
 
 #define BUFFER_SIZE (4096 * 16)
+
+/* Worst-case size in bytes of a 64-bit value encoded with LEB128. */
+#define LEB128_SIZE 10
+/* Size in bytes of the event ID prefix. */
+#define EVENT_SIZE 1
+
 static int nocalls = 0;
 static int notraces = 0;
 static int use_zip = 0;
@@ -192,8 +198,8 @@ typedef struct _LogBuffer LogBuffer;
  *
  * type GC format:
  * type: TYPE_GC
- * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED,
- * TYPE_GC_HANDLE_DESTROYED
+ * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED[_BT],
+ * TYPE_GC_HANDLE_DESTROYED[_BT]
  * [time diff: uleb128] nanoseconds since last timing
  * if exinfo == TYPE_GC_RESIZE
  *     [heap_size: uleb128] new heap size
@@ -205,15 +211,17 @@ typedef struct _LogBuffer LogBuffer;
  *     [objaddr: sleb128]+ num_objects object pointer differences from obj_base
  *     num is always an even number: the even items are the old
  *     addresses, the odd numbers are the respective new object addresses
- * if exinfo == TYPE_GC_HANDLE_CREATED
+ * if exinfo == TYPE_GC_HANDLE_CREATED[_BT]
  *     [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
  *     upper bits reserved as flags
  *     [handle: uleb128] GC handle value
  *     [objaddr: sleb128] object pointer differences from obj_base
- * if exinfo == TYPE_GC_HANDLE_DESTROYED
+ *     If exinfo == TYPE_GC_HANDLE_CREATED_BT, a backtrace follows.
+ * if exinfo == TYPE_GC_HANDLE_DESTROYED[_BT]
  *     [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
  *     upper bits reserved as flags
  *     [handle: uleb128] GC handle value
+ *     If exinfo == TYPE_GC_HANDLE_DESTROYED_BT, a backtrace follows.
  *
  * type metadata format:
  * type: TYPE_METADATA
@@ -222,19 +230,25 @@ typedef struct _LogBuffer LogBuffer;
  * [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
- * [flags: uleb128] must be 0
  * if mtype == TYPE_CLASS
  *     [image: sleb128] MonoImage* as a pointer difference from ptr_base
+ *     [flags: uleb128] must be 0
  *     [name: string] full class name
  * if mtype == TYPE_IMAGE
+ *     [flags: uleb128] must be 0
  *     [name: string] image file name
  * if mtype == TYPE_ASSEMBLY
+ *     [flags: uleb128] must be 0
  *     [name: string] assembly name
+ * if mtype == TYPE_DOMAIN
+ *     [flags: uleb128] must be 0
  * if mtype == TYPE_DOMAIN && exinfo == 0
  *     [name: string] domain friendly name
  * if mtype == TYPE_CONTEXT
+ *     [flags: uleb128] must be 0
  *     [domain: sleb128] domain id as pointer
  * if mtype == TYPE_THREAD && (format_version < 11 || (format_version > 10 && exinfo == 0))
+ *     [flags: uleb128] must be 0
  *     [name: string] thread name
  *
  * type method format:
@@ -475,6 +489,7 @@ typedef struct _MethodInfo MethodInfo;
 struct _MethodInfo {
        MonoMethod *method;
        MonoJitInfo *ji;
+       uint64_t time;
 };
 
 #ifdef TLS_INIT
@@ -507,7 +522,7 @@ static char*
 pstrdup (const char *s)
 {
        int len = strlen (s) + 1;
-       char *p = malloc (len);
+       char *p = (char *)malloc (len);
        memcpy (p, s, len);
        return p;
 }
@@ -515,7 +530,7 @@ pstrdup (const char *s)
 static StatBuffer*
 create_stat_buffer (void)
 {
-       StatBuffer* buf = alloc_buffer (BUFFER_SIZE);
+       StatBuffer* buf = (StatBuffer *)alloc_buffer (BUFFER_SIZE);
        buf->size = BUFFER_SIZE;
        buf->data_end = (uintptr_t*)((unsigned char*)buf + buf->size);
        buf->data = buf->buf;
@@ -525,7 +540,7 @@ create_stat_buffer (void)
 static LogBuffer*
 create_buffer (void)
 {
-       LogBuffer* buf = alloc_buffer (BUFFER_SIZE);
+       LogBuffer* buf = (LogBuffer *)alloc_buffer (BUFFER_SIZE);
        buf->size = BUFFER_SIZE;
        buf->time_base = current_time ();
        buf->last_time = buf->time_base;
@@ -556,29 +571,29 @@ ensure_logbuf_inner (LogBuffer *old, int bytes)
        if (old && old->data + bytes + 100 < old->data_end)
                return old;
 
-       LogBuffer *new = create_buffer ();
-       new->thread_id = thread_id ();
-       new->next = old;
+       LogBuffer *new_ = (LogBuffer *)create_buffer ();
+       new_->thread_id = thread_id ();
+       new_->next = old;
 
        if (old)
-               new->call_depth = old->call_depth;
+               new_->call_depth = old->call_depth;
 
-       return new;
+       return new_;
 }
 
 static LogBuffer*
 ensure_logbuf (int bytes)
 {
        LogBuffer *old = TLS_GET (LogBuffer, tlsbuffer);
-       LogBuffer *new = ensure_logbuf_inner (old, bytes);
+       LogBuffer *new_ = ensure_logbuf_inner (old, bytes);
 
-       if (new == old)
+       if (new_ == old)
                return old; // Still enough space.
 
-       TLS_SET (tlsbuffer, new);
+       TLS_SET (tlsbuffer, new_);
        init_thread ();
 
-       return new;
+       return new_;
 }
 
 static void
@@ -600,8 +615,8 @@ static void
 emit_time (LogBuffer *logbuffer, uint64_t value)
 {
        uint64_t tdiff = value - logbuffer->last_time;
-       if (value < logbuffer->last_time)
-               printf ("time went backwards\n");
+       //if (value < logbuffer->last_time)
+       //      printf ("time went backwards\n");
        //if (tdiff > 1000000)
        //      printf ("large time offset: %llu\n", tdiff);
        encode_uleb128 (tdiff, logbuffer->data, &logbuffer->data);
@@ -646,6 +661,7 @@ emit_method_inner (LogBuffer *logbuffer, void *method)
        assert (logbuffer->data <= logbuffer->data_end);
 }
 
+/*
 typedef struct {
        MonoMethod *method;
        MonoJitInfo *found;
@@ -673,11 +689,20 @@ find_method (MonoDomain *domain, void *user_data)
        if (ji)
                search->found = ji;
 }
+*/
 
 static void
 register_method_local (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji)
 {
        if (!mono_conc_hashtable_lookup (prof->method_table, method)) {
+               /*
+                * FIXME: In some cases, we crash while looking up JIT info for AOT'd methods.
+                * This usually happens for static constructors. This code is disabled for now
+                * as we don't need this info for anything critical.
+                *
+                * https://bugzilla.xamarin.com/show_bug.cgi?id=35171
+                */
+               /*
                if (!ji) {
                        MethodSearch search = { method, NULL };
 
@@ -685,13 +710,21 @@ register_method_local (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji)
 
                        ji = search.found;
                }
+               */
 
-               g_assert (ji);
+               /*
+                * FIXME: We can't always find JIT info for a generic shared method, especially
+                * if we obtained the MonoMethod during an async stack walk. For now, we deal
+                * with this by giving the generic shared method name and dummy code start/size
+                * information (i.e. zeroes).
+                */
+               //g_assert (ji);
 
-               MethodInfo *info = malloc (sizeof (MethodInfo));
+               MethodInfo *info = (MethodInfo *)malloc (sizeof (MethodInfo));
 
                info->method = method;
                info->ji = ji;
+               info->time = current_time ();
 
                g_ptr_array_add (TLS_GET (GPtrArray, tlsmethodlist), info);
        }
@@ -812,7 +845,7 @@ dump_header (MonoProfiler *profiler)
 static void
 send_buffer (MonoProfiler *prof, GPtrArray *methods, LogBuffer *buffer)
 {
-       WriterQueueEntry *entry = calloc (1, sizeof (WriterQueueEntry));
+       WriterQueueEntry *entry = (WriterQueueEntry *)calloc (1, sizeof (WriterQueueEntry));
        mono_lock_free_queue_node_init (&entry->node, FALSE);
        entry->methods = methods;
        entry->buffer = buffer;
@@ -892,7 +925,17 @@ gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num,
        int i;
        uintptr_t last_offset = 0;
        //const char *name = mono_class_get_name (klass);
-       LogBuffer *logbuffer = ensure_logbuf (20 + num * 8);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* obj */ +
+               LEB128_SIZE /* klass */ +
+               LEB128_SIZE /* size */ +
+               LEB128_SIZE /* num */ +
+               num * (
+                       LEB128_SIZE /* offset */ +
+                       LEB128_SIZE /* ref */
+               )
+       );
        emit_byte (logbuffer, TYPE_HEAP_OBJECT | TYPE_HEAP);
        emit_obj (logbuffer, obj);
        emit_ptr (logbuffer, klass);
@@ -925,7 +968,10 @@ heap_walk (MonoProfiler *profiler)
        LogBuffer *logbuffer;
        if (!do_heap_shot)
                return;
-       logbuffer = ensure_logbuf (10);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */
+       );
        now = current_time ();
        if (hs_mode_ms && (now - last_hs_time)/1000000 >= hs_mode_ms)
                do_walk = 1;
@@ -942,7 +988,10 @@ heap_walk (MonoProfiler *profiler)
        emit_byte (logbuffer, TYPE_HEAP_START | TYPE_HEAP);
        emit_time (logbuffer, now);
        mono_gc_walk_heap (0, gc_reference, NULL);
-       logbuffer = ensure_logbuf (10);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */
+       );
        now = current_time ();
        emit_byte (logbuffer, TYPE_HEAP_END | TYPE_HEAP);
        emit_time (logbuffer, now);
@@ -952,7 +1001,12 @@ heap_walk (MonoProfiler *profiler)
 static void
 gc_event (MonoProfiler *profiler, MonoGCEvent ev, int generation) {
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (10);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* gc event */ +
+               LEB128_SIZE /* generation */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "gcevent");
        emit_byte (logbuffer, TYPE_GC_EVENT | TYPE_GC);
@@ -976,7 +1030,11 @@ gc_event (MonoProfiler *profiler, MonoGCEvent ev, int generation) {
 static void
 gc_resize (MonoProfiler *profiler, int64_t new_size) {
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (10);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* new size */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "gcresize");
        emit_byte (logbuffer, TYPE_GC_RESIZE | TYPE_GC);
@@ -998,7 +1056,7 @@ static int num_frames = MAX_FRAMES;
 static mono_bool
 walk_stack (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data)
 {
-       FrameData *frame = data;
+       FrameData *frame = (FrameData *)data;
        if (method && frame->count < num_frames) {
                frame->il_offsets [frame->count] = il_offset;
                frame->native_offsets [frame->count] = native_offset;
@@ -1051,7 +1109,20 @@ gc_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass)
        len &= ~7;
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (32 + MAX_FRAMES * 8);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* klass */ +
+               LEB128_SIZE /* obj */ +
+               LEB128_SIZE /* size */ +
+               (do_bt ? (
+                       LEB128_SIZE /* flags */ +
+                       LEB128_SIZE /* count */ +
+                       data.count * (
+                               LEB128_SIZE /* method */
+                       )
+               ) : 0)
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "gcalloc");
        emit_byte (logbuffer, do_bt | TYPE_ALLOC);
@@ -1073,7 +1144,14 @@ gc_moves (MonoProfiler *prof, void **objects, int num)
 {
        int i;
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (10 + num * 8);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* num */ +
+               num * (
+                       LEB128_SIZE /* object */
+               )
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "gcmove");
        emit_byte (logbuffer, TYPE_GC_MOVE | TYPE_GC);
@@ -1089,7 +1167,16 @@ static void
 gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_t *extra_info)
 {
        int i;
-       LogBuffer *logbuffer = ensure_logbuf (5 + num * 18);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* num */ +
+               LEB128_SIZE /* collections */ +
+               num * (
+                       LEB128_SIZE /* object */ +
+                       LEB128_SIZE /* root type */ +
+                       LEB128_SIZE /* extra info */
+               )
+       );
        ENTER_LOG (logbuffer, "gcroots");
        emit_byte (logbuffer, TYPE_HEAP_ROOT | TYPE_HEAP);
        emit_value (logbuffer, num);
@@ -1105,21 +1192,50 @@ gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_
 static void
 gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj)
 {
+       int do_bt = nocalls && InterlockedRead (&runtime_inited) && !notraces;
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (16);
+       FrameData data;
+
+       if (do_bt)
+               collect_bt (&data);
+
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* type */ +
+               LEB128_SIZE /* handle */ +
+               (op == MONO_PROFILER_GC_HANDLE_CREATED ? (
+                       LEB128_SIZE /* obj */
+               ) : 0) +
+               (do_bt ? (
+                       LEB128_SIZE /* flags */ +
+                       LEB128_SIZE /* count */ +
+                       data.count * (
+                               LEB128_SIZE /* method */
+                       )
+               ) : 0)
+       );
+
        now = current_time ();
        ENTER_LOG (logbuffer, "gchandle");
+
        if (op == MONO_PROFILER_GC_HANDLE_CREATED)
-               emit_byte (logbuffer, TYPE_GC_HANDLE_CREATED | TYPE_GC);
+               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
        else if (op == MONO_PROFILER_GC_HANDLE_DESTROYED)
-               emit_byte (logbuffer, TYPE_GC_HANDLE_DESTROYED | TYPE_GC);
+               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
        else
-               return;
+               g_assert_not_reached ();
+
        emit_time (logbuffer, now);
        emit_value (logbuffer, type);
        emit_value (logbuffer, handle);
+
        if (op == MONO_PROFILER_GC_HANDLE_CREATED)
                emit_obj (logbuffer, obj);
+
+       if (do_bt)
+               emit_bt (prof, logbuffer, &data);
+
        EXIT_LOG (logbuffer);
        process_requests (prof);
 }
@@ -1155,7 +1271,7 @@ type_name (MonoClass *klass)
        char buf [1024];
        char *p;
        push_nesting (buf, klass);
-       p = malloc (strlen (buf) + 1);
+       p = (char *)malloc (strlen (buf) + 1);
        strcpy (p, buf);
        return p;
 }
@@ -1171,7 +1287,14 @@ image_loaded (MonoProfiler *prof, MonoImage *image, int result)
                return;
        name = mono_image_get_filename (image);
        nlen = strlen (name) + 1;
-       logbuffer = ensure_logbuf (16 + nlen);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* image */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "image");
        emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
@@ -1193,7 +1316,14 @@ image_unloaded (MonoProfiler *prof, MonoImage *image)
 {
        const char *name = mono_image_get_filename (image);
        int nlen = strlen (name) + 1;
-       LogBuffer *logbuffer = ensure_logbuf (16 + nlen);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* image */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "image-unload");
@@ -1220,7 +1350,14 @@ assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly, int result)
 
        char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
        int nlen = strlen (name) + 1;
-       LogBuffer *logbuffer = ensure_logbuf (20 + nlen);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* assembly */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "assembly-load");
@@ -1246,7 +1383,14 @@ assembly_unloaded (MonoProfiler *prof, MonoAssembly *assembly)
 {
        char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
        int nlen = strlen (name) + 1;
-       LogBuffer *logbuffer = ensure_logbuf (20 + nlen);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* assembly */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "assembly-unload");
@@ -1283,7 +1427,15 @@ class_loaded (MonoProfiler *prof, MonoClass *klass, int result)
                name = type_name (klass);
        nlen = strlen (name) + 1;
        image = mono_class_get_image (klass);
-       logbuffer = ensure_logbuf (24 + nlen);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* klass */ +
+               LEB128_SIZE /* image */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "class");
        emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
@@ -1317,7 +1469,15 @@ class_unloaded (MonoProfiler *prof, MonoClass *klass)
 
        int nlen = strlen (name) + 1;
        MonoImage *image = mono_class_get_image (klass);
-       LogBuffer *logbuffer = ensure_logbuf (24 + nlen);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* klass */ +
+               LEB128_SIZE /* image */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "class-unload");
@@ -1355,7 +1515,11 @@ method_enter (MonoProfiler *prof, MonoMethod *method)
        process_method_enter_coverage (prof, method);
 #endif /* DISABLE_HELPER_THREAD */
 
-       LogBuffer *logbuffer = ensure_logbuf (16);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* method */
+       );
        if (logbuffer->call_depth++ > max_call_depth)
                return;
        ENTER_LOG (logbuffer, "enter");
@@ -1371,7 +1535,11 @@ static void
 method_leave (MonoProfiler *prof, MonoMethod *method)
 {
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (16);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* method */
+       );
        if (--logbuffer->call_depth > max_call_depth)
                return;
        now = current_time ();
@@ -1392,7 +1560,11 @@ method_exc_leave (MonoProfiler *prof, MonoMethod *method)
        LogBuffer *logbuffer;
        if (nocalls)
                return;
-       logbuffer = ensure_logbuf (16);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* method */
+       );
        if (--logbuffer->call_depth > max_call_depth)
                return;
        now = current_time ();
@@ -1411,6 +1583,8 @@ method_jitted (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji, int resu
                return;
 
        register_method_local (prof, method, ji);
+
+       process_requests (prof);
 }
 
 static void
@@ -1421,13 +1595,22 @@ code_buffer_new (MonoProfiler *prof, void *buffer, int size, MonoProfilerCodeBuf
        char *name;
        LogBuffer *logbuffer;
        if (type == MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE) {
-               name = data;
+               name = (char *)data;
                nlen = strlen (name) + 1;
        } else {
                name = NULL;
                nlen = 0;
        }
-       logbuffer = ensure_logbuf (32 + nlen);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* type */ +
+               LEB128_SIZE /* buffer */ +
+               LEB128_SIZE /* size */ +
+               (name ? (
+                       nlen /* name */
+               ) : 0)
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "code buffer");
        emit_byte (logbuffer, TYPE_JITHELPER | TYPE_RUNTIME);
@@ -1452,7 +1635,18 @@ throw_exc (MonoProfiler *prof, MonoObject *object)
        LogBuffer *logbuffer;
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* object */ +
+               (do_bt ? (
+                       LEB128_SIZE /* flags */ +
+                       LEB128_SIZE /* count */ +
+                       data.count * (
+                               LEB128_SIZE /* method */
+                       )
+               ) : 0)
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "throw");
        emit_byte (logbuffer, do_bt | TYPE_EXCEPTION);
@@ -1468,7 +1662,13 @@ static void
 clause_exc (MonoProfiler *prof, MonoMethod *method, int clause_type, int clause_num)
 {
        uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (16);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* clause type */ +
+               LEB128_SIZE /* clause num */ +
+               LEB128_SIZE /* method */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "clause");
        emit_byte (logbuffer, TYPE_EXCEPTION | TYPE_CLAUSE);
@@ -1477,6 +1677,8 @@ clause_exc (MonoProfiler *prof, MonoMethod *method, int clause_type, int clause_
        emit_value (logbuffer, clause_num);
        emit_method (prof, logbuffer, method);
        EXIT_LOG (logbuffer);
+
+       process_requests (prof);
 }
 
 static void
@@ -1488,7 +1690,18 @@ monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEv
        LogBuffer *logbuffer;
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* object */ +
+               (do_bt ? (
+                       LEB128_SIZE /* flags */ +
+                       LEB128_SIZE /* count */ +
+                       data.count * (
+                               LEB128_SIZE /* method */
+                       )
+               ) : 0)
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "monitor");
        emit_byte (logbuffer, (event << 4) | do_bt | TYPE_MONITOR);
@@ -1506,7 +1719,13 @@ thread_start (MonoProfiler *prof, uintptr_t tid)
        //printf ("thread start %p\n", (void*)tid);
        init_thread ();
 
-       LogBuffer *logbuffer = ensure_logbuf (20);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* tid */ +
+               LEB128_SIZE /* flags */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "thread-start");
@@ -1527,7 +1746,13 @@ static void
 thread_end (MonoProfiler *prof, uintptr_t tid)
 {
        if (TLS_GET (LogBuffer, tlsbuffer)) {
-               LogBuffer *logbuffer = ensure_logbuf (20);
+               LogBuffer *logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* time */ +
+                       EVENT_SIZE /* type */ +
+                       LEB128_SIZE /* tid */ +
+                       LEB128_SIZE /* flags */
+               );
                uint64_t now = current_time ();
 
                ENTER_LOG (logbuffer, "thread-end");
@@ -1539,6 +1764,8 @@ thread_end (MonoProfiler *prof, uintptr_t tid)
                EXIT_LOG (logbuffer);
 
                send_buffer (prof, TLS_GET (GPtrArray, tlsmethodlist), logbuffer);
+
+               /* Don't process requests as the thread is detached from the runtime. */
        }
 
        TLS_SET (tlsbuffer, NULL);
@@ -1551,7 +1778,13 @@ domain_loaded (MonoProfiler *prof, MonoDomain *domain, int result)
        if (result != MONO_PROFILE_OK)
                return;
 
-       LogBuffer *logbuffer = ensure_logbuf (20);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* domain id */ +
+               LEB128_SIZE /* flags */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "domain-start");
@@ -1571,7 +1804,13 @@ domain_loaded (MonoProfiler *prof, MonoDomain *domain, int result)
 static void
 domain_unloaded (MonoProfiler *prof, MonoDomain *domain)
 {
-       LogBuffer *logbuffer = ensure_logbuf (20);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* domain id */ +
+               LEB128_SIZE /* flags */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "domain-end");
@@ -1592,7 +1831,14 @@ static void
 domain_name (MonoProfiler *prof, MonoDomain *domain, const char *name)
 {
        int nlen = strlen (name) + 1;
-       LogBuffer *logbuffer = ensure_logbuf (20 + nlen);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* domain id */ +
+               LEB128_SIZE /* flags */ +
+               nlen /* name */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "domain-name");
@@ -1614,7 +1860,14 @@ domain_name (MonoProfiler *prof, MonoDomain *domain, const char *name)
 static void
 context_loaded (MonoProfiler *prof, MonoAppContext *context)
 {
-       LogBuffer *logbuffer = ensure_logbuf (28);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* context id */ +
+               LEB128_SIZE /* flags */ +
+               LEB128_SIZE /* domain id */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "context-start");
@@ -1635,7 +1888,14 @@ context_loaded (MonoProfiler *prof, MonoAppContext *context)
 static void
 context_unloaded (MonoProfiler *prof, MonoAppContext *context)
 {
-       LogBuffer *logbuffer = ensure_logbuf (28);
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* context id */ +
+               LEB128_SIZE /* flags */ +
+               LEB128_SIZE /* domain id */
+       );
        uint64_t now = current_time ();
 
        ENTER_LOG (logbuffer, "context-end");
@@ -1659,7 +1919,14 @@ thread_name (MonoProfiler *prof, uintptr_t tid, const char *name)
        int len = strlen (name) + 1;
        uint64_t now;
        LogBuffer *logbuffer;
-       logbuffer = ensure_logbuf (10 + len);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               EVENT_SIZE /* type */ +
+               LEB128_SIZE /* tid */ +
+               LEB128_SIZE /* flags */ +
+               len /* name */
+       );
        now = current_time ();
        ENTER_LOG (logbuffer, "tname");
        emit_byte (logbuffer, TYPE_METADATA);
@@ -1692,7 +1959,7 @@ typedef struct {
 static mono_bool
 async_walk_stack (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void *data)
 {
-       AsyncFrameData *frame = data;
+       AsyncFrameData *frame = (AsyncFrameData *)data;
        if (frame->count < num_frames) {
                frame->data [frame->count].method = method;
                frame->data [frame->count].domain = domain;
@@ -1750,7 +2017,7 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
                do {
                        oldsb = profiler->stat_buffers;
                        sbuf->next = oldsb;
-                       foundsb = InterlockedCompareExchangePointer ((void * volatile*)&profiler->stat_buffers, sbuf, oldsb);
+                       foundsb = (StatBuffer *)InterlockedCompareExchangePointer ((void * volatile*)&profiler->stat_buffers, sbuf, oldsb);
                } while (foundsb != oldsb);
                if (do_debug)
                        ign_res (write (2, "overflow\n", 9));
@@ -1765,7 +2032,7 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
        do {
                old_data = sbuf->data;
                new_data = old_data + SAMPLE_EVENT_SIZE_IN_SLOTS (bt_data.count);
-               data = InterlockedCompareExchangePointer ((void * volatile*)&sbuf->data, new_data, old_data);
+               data = (uintptr_t *)InterlockedCompareExchangePointer ((void * volatile*)&sbuf->data, new_data, old_data);
        } while (data != old_data);
        if (old_data >= sbuf->data_end)
                return; /* lost event */
@@ -1822,7 +2089,7 @@ add_code_pointer (uintptr_t ip)
                size_code_pages *= 2;
                if (size_code_pages == 0)
                        size_code_pages = 16;
-               n = calloc (sizeof (uintptr_t) * size_code_pages, 1);
+               n = (uintptr_t *)calloc (sizeof (uintptr_t) * size_code_pages, 1);
                for (i = 0; i < old_size; ++i) {
                        if (code_pages [i])
                                add_code_page (n, size_code_pages, code_pages [i]);
@@ -1845,7 +2112,14 @@ dump_ubin (const char *filename, uintptr_t load_addr, uint64_t offset, uintptr_t
        int len;
        len = strlen (filename) + 1;
        now = current_time ();
-       logbuffer = ensure_logbuf (20 + len);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */ +
+               LEB128_SIZE /* load address */ +
+               LEB128_SIZE /* offset */ +
+               LEB128_SIZE /* size */ +
+               nlen /* file name */
+       );
        emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_UBIN);
        emit_time (logbuffer, now);
        emit_svalue (logbuffer, load_addr);
@@ -1862,7 +2136,12 @@ dump_usym (const char *name, uintptr_t value, uintptr_t size)
        LogBuffer *logbuffer;
        int len;
        len = strlen (name) + 1;
-       logbuffer = ensure_logbuf (20 + len);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* value */ +
+               LEB128_SIZE /* size */ +
+               len /* name */
+       );
        emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_USYM);
        emit_ptr (logbuffer, (void*)value);
        emit_value (logbuffer, size);
@@ -2146,7 +2425,7 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf)
        g_ptr_array_sort (prof->sorted_sample_events, compare_sample_events);
 
        for (guint sidx = 0; sidx < prof->sorted_sample_events->len; sidx++) {
-               uintptr_t *sample = g_ptr_array_index (prof->sorted_sample_events, sidx);
+               uintptr_t *sample = (uintptr_t *)g_ptr_array_index (prof->sorted_sample_events, sidx);
                int count = sample [0] & 0xff;
                int mbt_count = (sample [0] & 0xff00) >> 8;
                int type = sample [0] >> 16;
@@ -2159,14 +2438,29 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf)
                        void *address = (void*)managed_sample_base [i * 4 + 2];
 
                        if (!method) {
-                               MonoJitInfo *ji = mono_jit_info_table_find (domain, address);
+                               MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *)address);
 
                                if (ji)
                                        managed_sample_base [i * 4 + 0] = (uintptr_t)mono_jit_info_get_method (ji);
                        }
                }
 
-               logbuffer = ensure_logbuf (20 + count * 8);
+               logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* type */ +
+                       LEB128_SIZE /* time */ +
+                       LEB128_SIZE /* tid */ +
+                       LEB128_SIZE /* count */ +
+                       count * (
+                               LEB128_SIZE /* ip */
+                       ) +
+                       LEB128_SIZE /* managed count */ +
+                       mbt_count * (
+                               LEB128_SIZE /* method */ +
+                               LEB128_SIZE /* il offset */ +
+                               LEB128_SIZE /* native offset */
+                       )
+               );
                emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
                emit_value (logbuffer, type);
                emit_uvalue (logbuffer, prof->startup_time + (uint64_t)sample [2] * (uint64_t)10000);
@@ -2302,6 +2596,8 @@ static void
 dump_perf_hits (MonoProfiler *prof, void *buf, int size)
 {
        LogBuffer *logbuffer;
+       int count = 1;
+       int mbt_count = 0;
        void *end = (char*)buf + size;
        int samples = 0;
        int pid = getpid ();
@@ -2319,7 +2615,22 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                /*ip = (void*)s->ip;
                printf ("sample: %d, size: %d, ip: %p (%s), timestamp: %llu, nframes: %llu\n",
                        s->h.type, s->h.size, ip, symbol_for (ip), s->timestamp, s->nframes);*/
-               logbuffer = ensure_logbuf (20 + s->nframes * 8);
+               logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* type */ +
+                       LEB128_SIZE /* time */ +
+                       LEB128_SIZE /* tid */ +
+                       LEB128_SIZE /* count */ +
+                       count * (
+                               LEB128_SIZE /* ip */
+                       ) +
+                       LEB128_SIZE /* managed count */ +
+                       mbt_count * (
+                               LEB128_SIZE /* method */ +
+                               LEB128_SIZE /* il offset */ +
+                               LEB128_SIZE /* native offset */
+                       )
+               );
                emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
                emit_value (logbuffer, sample_type);
                emit_uvalue (logbuffer, s->timestamp - prof->startup_time);
@@ -2329,11 +2640,11 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                 * perf is the kernel's thread ID.
                 */
                emit_ptr (logbuffer, 0);
-               emit_value (logbuffer, 1); /* count */
+               emit_value (logbuffer, count);
                emit_ptr (logbuffer, (void*)(uintptr_t)s->ip);
-               /* no support here yet for the managed backtrace */
-               emit_uvalue (logbuffer, 0);
                add_code_pointer (s->ip);
+               /* no support here yet for the managed backtrace */
+               emit_uvalue (logbuffer, mbt_count);
                buf = (char*)buf + s->h.size;
                samples++;
        }
@@ -2470,7 +2781,7 @@ counters_add_agent (MonoCounter *counter)
        if (!counters_initialized)
                return;
 
-       mono_mutex_lock (&counters_mutex);
+       mono_os_mutex_lock (&counters_mutex);
 
        for (agent = counters; agent; agent = agent->next) {
                if (agent->counter == counter) {
@@ -2479,12 +2790,12 @@ counters_add_agent (MonoCounter *counter)
                                free (agent->value);
                                agent->value = NULL;
                        }
-                       mono_mutex_unlock (&counters_mutex);
+                       mono_os_mutex_unlock (&counters_mutex);
                        return;
                }
        }
 
-       agent = malloc (sizeof (MonoCounterAgent));
+       agent = (MonoCounterAgent *)malloc (sizeof (MonoCounterAgent));
        agent->counter = counter;
        agent->value = NULL;
        agent->value_size = 0;
@@ -2501,7 +2812,7 @@ counters_add_agent (MonoCounter *counter)
                item->next = agent;
        }
 
-       mono_mutex_unlock (&counters_mutex);
+       mono_os_mutex_unlock (&counters_mutex);
 }
 
 static mono_bool
@@ -2516,7 +2827,7 @@ counters_init (MonoProfiler *profiler)
 {
        assert (!counters_initialized);
 
-       mono_mutex_init (&counters_mutex);
+       mono_os_mutex_init (&counters_mutex);
 
        counters_initialized = TRUE;
 
@@ -2529,23 +2840,35 @@ counters_emit (MonoProfiler *profiler)
 {
        MonoCounterAgent *agent;
        LogBuffer *logbuffer;
-       int size = 1 + 5, len = 0;
+       int len = 0;
+       int size =
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* len */
+       ;
 
        if (!counters_initialized)
                return;
 
-       mono_mutex_lock (&counters_mutex);
+       mono_os_mutex_lock (&counters_mutex);
 
        for (agent = counters; agent; agent = agent->next) {
                if (agent->emitted)
                        continue;
 
-               size += strlen (mono_counter_get_name (agent->counter)) + 1 + 5 * 5;
+               size +=
+                       LEB128_SIZE /* section */ +
+                       strlen (mono_counter_get_name (agent->counter)) + 1 /* name */ +
+                       LEB128_SIZE /* type */ +
+                       LEB128_SIZE /* unit */ +
+                       LEB128_SIZE /* variance */ +
+                       LEB128_SIZE /* index */
+               ;
+
                len += 1;
        }
 
        if (!len) {
-               mono_mutex_unlock (&counters_mutex);
+               mono_os_mutex_unlock (&counters_mutex);
                return;
        }
 
@@ -2572,9 +2895,9 @@ counters_emit (MonoProfiler *profiler)
        }
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, ensure_logbuf (0));
+       safe_send (profiler, logbuffer);
 
-       mono_mutex_unlock (&counters_mutex);
+       mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
@@ -2596,11 +2919,24 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        buffer_size = 8;
        buffer = calloc (1, buffer_size);
 
-       mono_mutex_lock (&counters_mutex);
+       mono_os_mutex_lock (&counters_mutex);
+
+       size =
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */
+       ;
+
+       for (agent = counters; agent; agent = agent->next) {
+               size +=
+                       LEB128_SIZE /* index */ +
+                       LEB128_SIZE /* type */ +
+                       mono_counter_get_size (agent->counter) /* value */
+               ;
+       }
 
-       size = 1 + 10 + 5;
-       for (agent = counters; agent; agent = agent->next)
-               size += 10 * 2 + mono_counter_get_size (agent->counter);
+       size +=
+               LEB128_SIZE /* stop marker */
+       ;
 
        logbuffer = ensure_logbuf (size);
 
@@ -2690,9 +3026,9 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        emit_value (logbuffer, 0);
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, ensure_logbuf (0));
+       safe_send (profiler, logbuffer);
 
-       mono_mutex_unlock (&counters_mutex);
+       mono_os_mutex_unlock (&counters_mutex);
 }
 
 typedef struct _PerfCounterAgent PerfCounterAgent;
@@ -2715,13 +3051,26 @@ perfcounters_emit (MonoProfiler *profiler)
 {
        PerfCounterAgent *pcagent;
        LogBuffer *logbuffer;
-       int size = 1 + 5, len = 0;
+       int len = 0;
+       int size =
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* len */
+       ;
 
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
                if (pcagent->emitted)
                        continue;
 
-               size += strlen (pcagent->name) + 1 + 5 * 5;
+               size +=
+                       LEB128_SIZE /* section */ +
+                       strlen (pcagent->category_name) + 1 /* category name */ +
+                       strlen (pcagent->name) + 1 /* name */ +
+                       LEB128_SIZE /* type */ +
+                       LEB128_SIZE /* unit */ +
+                       LEB128_SIZE /* variance */ +
+                       LEB128_SIZE /* index */
+               ;
+
                len += 1;
        }
 
@@ -2749,7 +3098,7 @@ perfcounters_emit (MonoProfiler *profiler)
        }
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, ensure_logbuf (0));
+       safe_send (profiler, logbuffer);
 }
 
 static gboolean
@@ -2795,7 +3144,7 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
        if (!counters_initialized)
                return;
 
-       mono_mutex_lock (&counters_mutex);
+       mono_os_mutex_lock (&counters_mutex);
 
        /* mark all perfcounters as deleted, foreach will unmark them as necessary */
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next)
@@ -2805,14 +3154,26 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
 
        perfcounters_emit (profiler);
 
+       size =
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* time */
+       ;
 
-       size = 1 + 10 + 5;
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
                if (pcagent->deleted || !pcagent->updated)
                        continue;
-               size += 10 * 2 + sizeof (gint64);
+
+               size +=
+                       LEB128_SIZE /* index */ +
+                       LEB128_SIZE /* type */ +
+                       LEB128_SIZE /* value */
+               ;
        }
 
+       size +=
+               LEB128_SIZE /* stop marker */
+       ;
+
        logbuffer = ensure_logbuf (size);
 
        ENTER_LOG (logbuffer, "perfcounters");
@@ -2831,9 +3192,9 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
        emit_value (logbuffer, 0);
        EXIT_LOG (logbuffer);
 
-       safe_send (profiler, ensure_logbuf (0));
+       safe_send (profiler, logbuffer);
 
-       mono_mutex_unlock (&counters_mutex);
+       mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
@@ -2851,20 +3212,15 @@ counters_and_perfcounters_sample (MonoProfiler *prof)
 }
 
 #define COVERAGE_DEBUG(x) if (debug_coverage) {x}
+static mono_mutex_t coverage_mutex;
 static MonoConcurrentHashTable *coverage_methods = NULL;
-static mono_mutex_t coverage_methods_mutex;
 static MonoConcurrentHashTable *coverage_assemblies = NULL;
-static mono_mutex_t coverage_assemblies_mutex;
 static MonoConcurrentHashTable *coverage_classes = NULL;
-static mono_mutex_t coverage_classes_mutex;
+
 static MonoConcurrentHashTable *filtered_classes = NULL;
-static mono_mutex_t filtered_classes_mutex;
 static MonoConcurrentHashTable *entered_methods = NULL;
-static mono_mutex_t entered_methods_mutex;
 static MonoConcurrentHashTable *image_to_methods = NULL;
-static mono_mutex_t image_to_methods_mutex;
 static MonoConcurrentHashTable *suppressed_assemblies = NULL;
-static mono_mutex_t suppressed_assemblies_mutex;
 static gboolean coverage_initialized = FALSE;
 
 static GPtrArray *coverage_data = NULL;
@@ -2919,7 +3275,7 @@ parse_generic_type_names(char *name)
        if (name == NULL || *name == '\0')
                return g_strdup ("");
 
-       if (!(ret = new_name = calloc (strlen (name) * 4 + 1, sizeof (char))))
+       if (!(ret = new_name = (char *)calloc (strlen (name) * 4 + 1, sizeof (char))))
                return NULL;
 
        do {
@@ -2968,7 +3324,6 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        char *class_name;
        const char *image_name, *method_name, *sig, *first_filename;
        LogBuffer *logbuffer;
-       int size = 1;
        guint i;
 
        previous_offset = 0;
@@ -2985,7 +3340,7 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        method_name = mono_method_get_name (method);
 
        if (coverage_data->len != 0) {
-               CoverageEntry *entry = coverage_data->pdata[0];
+               CoverageEntry *entry = (CoverageEntry *)coverage_data->pdata[0];
                first_filename = entry->filename ? entry->filename : "";
        } else
                first_filename = "";
@@ -2994,15 +3349,17 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        sig = sig ? sig : "";
        method_name = method_name ? method_name : "";
 
-       size += strlen (image_name) + 1;
-       size += strlen (class_name) + 1;
-       size += strlen (method_name) + 1;
-       size += strlen (first_filename) + 1;
-       size += strlen (sig) + 1;
-
-       size += 10 + 10 + 5; /* token + method_id + n_entries*/
-
-       logbuffer = ensure_logbuf (size);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               strlen (image_name) + 1 /* image name */ +
+               strlen (class_name) + 1 /* class name */ +
+               strlen (method_name) + 1 /* method name */ +
+               strlen (sig) + 1 /* signature */ +
+               strlen (first_filename) + 1 /* first file name */ +
+               LEB128_SIZE /* token */ +
+               LEB128_SIZE /* method id */ +
+               LEB128_SIZE /* entries */
+       );
        ENTER_LOG (logbuffer, "coverage-methods");
 
        emit_byte (logbuffer, TYPE_COVERAGE_METHOD | TYPE_COVERAGE);
@@ -3017,15 +3374,19 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        emit_value (logbuffer, coverage_data->len);
 
        EXIT_LOG (logbuffer);
-       safe_send (prof, ensure_logbuf (0));
+       safe_send (prof, logbuffer);
 
        for (i = 0; i < coverage_data->len; i++) {
-               CoverageEntry *entry = coverage_data->pdata[i];
-
-               size = 1;
-               size += 10 * 5; /* method_id, offset, count, line, column */
-
-               logbuffer = ensure_logbuf (size);
+               CoverageEntry *entry = (CoverageEntry *)coverage_data->pdata[i];
+
+               logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* method id */ +
+                       LEB128_SIZE /* offset */ +
+                       LEB128_SIZE /* counter */ +
+                       LEB128_SIZE /* line */ +
+                       LEB128_SIZE /* column */
+               );
                ENTER_LOG (logbuffer, "coverage-statement");
 
                emit_byte (logbuffer, TYPE_COVERAGE_STATEMENT | TYPE_COVERAGE);
@@ -3036,7 +3397,7 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
                emit_uvalue (logbuffer, entry->column);
 
                EXIT_LOG (logbuffer);
-               safe_send (prof, ensure_logbuf (0));
+               safe_send (prof, logbuffer);
        }
 
        method_id++;
@@ -3075,7 +3436,6 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
        int number_of_methods, partially_covered;
        guint fully_covered;
        LogBuffer *logbuffer;
-       int size = 1;
 
        image = mono_class_get_image (klass);
        assembly_name = mono_image_get_name (image);
@@ -3087,11 +3447,14 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
        /* We don't handle partial covered yet */
        partially_covered = 0;
 
-       size += strlen (assembly_name) + 1;
-       size += strlen (class_name) + 1;
-       size += 30; /* number_of_methods, fully_covered, partially_covered */
-
-       logbuffer = ensure_logbuf (size);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               strlen (assembly_name) + 1 /* assembly name */ +
+               strlen (class_name) + 1 /* class name */ +
+               LEB128_SIZE /* no. methods */ +
+               LEB128_SIZE /* fully covered */ +
+               LEB128_SIZE /* partially covered */
+       );
 
        ENTER_LOG (logbuffer, "coverage-class");
        emit_byte (logbuffer, TYPE_COVERAGE_CLASS | TYPE_COVERAGE);
@@ -3102,7 +3465,7 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
        emit_uvalue (logbuffer, partially_covered);
        EXIT_LOG (logbuffer);
 
-       safe_send (prof, ensure_logbuf (0));
+       safe_send (prof, logbuffer);
 
        g_free (class_name);
 }
@@ -3110,7 +3473,7 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
 static void
 get_coverage_for_image (MonoImage *image, int *number_of_methods, guint *fully_covered, int *partially_covered)
 {
-       MonoLockFreeQueue *image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
+       MonoLockFreeQueue *image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (image_to_methods, image);
 
        *number_of_methods = mono_image_get_table_rows (image, MONO_TABLE_METHOD);
        if (image_methods)
@@ -3130,7 +3493,6 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
        MonoImage *image = mono_assembly_get_image (assembly);
        LogBuffer *logbuffer;
        const char *name, *guid, *filename;
-       int size = 1;
        int number_of_methods = 0, partially_covered = 0;
        guint fully_covered = 0;
 
@@ -3144,11 +3506,15 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
 
        get_coverage_for_image (image, &number_of_methods, &fully_covered, &partially_covered);
 
-       size += strlen (name) + 1;
-       size += strlen (guid) + 1;
-       size += strlen (filename) + 1;
-       size += 30; /* number_of_methods, fully_covered, partially_covered */
-       logbuffer = ensure_logbuf (size);
+       logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               strlen (name) + 1 /* name */ +
+               strlen (guid) + 1 /* guid */ +
+               strlen (filename) + 1 /* file name */ +
+               LEB128_SIZE /* no. methods */ +
+               LEB128_SIZE /* fully covered */ +
+               LEB128_SIZE /* partially covered */
+       );
 
        ENTER_LOG (logbuffer, "coverage-assemblies");
        emit_byte (logbuffer, TYPE_COVERAGE_ASSEMBLY | TYPE_COVERAGE);
@@ -3160,7 +3526,7 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
        emit_uvalue (logbuffer, partially_covered);
        EXIT_LOG (logbuffer);
 
-       safe_send (prof, ensure_logbuf (0));
+       safe_send (prof, logbuffer);
 }
 
 static void
@@ -3172,9 +3538,11 @@ dump_coverage (MonoProfiler *prof)
        COVERAGE_DEBUG(fprintf (stderr, "Coverage: Started dump\n");)
        method_id = 0;
 
+       mono_os_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_foreach (coverage_assemblies, build_assembly_buffer, prof);
        mono_conc_hashtable_foreach (coverage_classes, build_class_buffer, prof);
        mono_conc_hashtable_foreach (coverage_methods, build_method_buffer, prof);
+       mono_os_mutex_unlock (&coverage_mutex);
 
        COVERAGE_DEBUG(fprintf (stderr, "Coverage: Finished dump\n");)
 }
@@ -3194,13 +3562,15 @@ process_method_enter_coverage (MonoProfiler *prof, MonoMethod *method)
        if (mono_conc_hashtable_lookup (suppressed_assemblies, (gpointer) mono_image_get_name (image)))
                return;
 
+       mono_os_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_insert (entered_methods, method, method);
+       mono_os_mutex_unlock (&coverage_mutex);
 }
 
 static MonoLockFreeQueueNode *
 create_method_node (MonoMethod *method)
 {
-       MethodNode *node = g_malloc (sizeof (MethodNode));
+       MethodNode *node = (MethodNode *)g_malloc (sizeof (MethodNode));
        mono_lock_free_queue_node_init ((MonoLockFreeQueueNode *) node, FALSE);
        node->method = method;
 
@@ -3261,7 +3631,7 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
                has_positive = FALSE;
                found = FALSE;
                for (guint i = 0; i < prof->coverage_filters->len; ++i) {
-                       char *filter = g_ptr_array_index (prof->coverage_filters, i);
+                       char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
 
                        if (filter [0] == '+') {
                                filter = &filter [1];
@@ -3281,7 +3651,9 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
                if (has_positive && !found) {
                        COVERAGE_DEBUG(fprintf (stderr, "   Positive match was not found\n");)
 
+                       mono_os_mutex_lock (&coverage_mutex);
                        mono_conc_hashtable_insert (filtered_classes, klass, klass);
+                       mono_os_mutex_unlock (&coverage_mutex);
                        g_free (fqn);
                        g_free (classname);
 
@@ -3290,7 +3662,7 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
 
                for (guint i = 0; i < prof->coverage_filters->len; ++i) {
                        // FIXME: Is substring search sufficient?
-                       char *filter = g_ptr_array_index (prof->coverage_filters, i);
+                       char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
                        if (filter [0] == '+')
                                continue;
 
@@ -3301,7 +3673,9 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
                        if (strstr (fqn, filter) != NULL) {
                                COVERAGE_DEBUG(fprintf (stderr, "matched\n");)
 
+                               mono_os_mutex_lock (&coverage_mutex);
                                mono_conc_hashtable_insert (filtered_classes, klass, klass);
+                               mono_os_mutex_unlock (&coverage_mutex);
                                g_free (fqn);
                                g_free (classname);
 
@@ -3322,26 +3696,32 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
 
        assembly = mono_image_get_assembly (image);
 
+       mono_os_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_insert (coverage_methods, method, method);
        mono_conc_hashtable_insert (coverage_assemblies, assembly, assembly);
+       mono_os_mutex_unlock (&coverage_mutex);
 
-       image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
+       image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (image_to_methods, image);
 
        if (image_methods == NULL) {
-               image_methods = g_malloc (sizeof (MonoLockFreeQueue));
+               image_methods = (MonoLockFreeQueue *)g_malloc (sizeof (MonoLockFreeQueue));
                mono_lock_free_queue_init (image_methods);
+               mono_os_mutex_lock (&coverage_mutex);
                mono_conc_hashtable_insert (image_to_methods, image, image_methods);
+               mono_os_mutex_unlock (&coverage_mutex);
        }
 
        node = create_method_node (method);
        mono_lock_free_queue_enqueue (image_methods, node);
 
-       class_methods = mono_conc_hashtable_lookup (coverage_classes, klass);
+       class_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (coverage_classes, klass);
 
        if (class_methods == NULL) {
-               class_methods = g_malloc (sizeof (MonoLockFreeQueue));
+               class_methods = (MonoLockFreeQueue *)g_malloc (sizeof (MonoLockFreeQueue));
                mono_lock_free_queue_init (class_methods);
+               mono_os_mutex_lock (&coverage_mutex);
                mono_conc_hashtable_insert (coverage_classes, klass, class_methods);
+               mono_os_mutex_unlock (&coverage_mutex);
        }
 
        node = create_method_node (method);
@@ -3376,7 +3756,7 @@ get_file_content (FILE *stream)
        if (filesize > MAX_FILE_SIZE)
          return NULL;
 
-       buffer = g_malloc ((filesize + 1) * sizeof (char));
+       buffer = (char *)g_malloc ((filesize + 1) * sizeof (char));
        while ((bytes_read = fread (buffer + offset, 1, LINE_BUFFER_SIZE, stream)) > 0)
                offset += bytes_read;
 
@@ -3414,8 +3794,7 @@ init_suppressed_assemblies (void)
        char *line;
        FILE *sa_file;
 
-       mono_mutex_init (&suppressed_assemblies_mutex);
-       suppressed_assemblies = mono_conc_hashtable_new (&suppressed_assemblies_mutex, g_str_hash, g_str_equal);
+       suppressed_assemblies = mono_conc_hashtable_new (g_str_hash, g_str_equal);
        sa_file = fopen (SUPPRESSION_DIR "/mono-profiler-log.suppression", "r");
        if (sa_file == NULL)
                return;
@@ -3428,26 +3807,13 @@ init_suppressed_assemblies (void)
 
        while ((line = get_next_line (content, &content))) {
                line = g_strchomp (g_strchug (line));
+               /* No locking needed as we're doing initialization */
                mono_conc_hashtable_insert (suppressed_assemblies, line, line);
        }
 
        fclose (sa_file);
 }
 
-static MonoConcurrentHashTable *
-init_hashtable (mono_mutex_t *mutex)
-{
-       mono_mutex_init (mutex);
-       return mono_conc_hashtable_new (mutex, NULL, NULL);
-}
-
-static void
-destroy_hashtable (MonoConcurrentHashTable *hashtable, mono_mutex_t *mutex)
-{
-       mono_conc_hashtable_destroy (hashtable);
-       mono_mutex_destroy (mutex);
-}
-
 #endif /* DISABLE_HELPER_THREAD */
 
 static void
@@ -3458,12 +3824,13 @@ coverage_init (MonoProfiler *prof)
 
        COVERAGE_DEBUG(fprintf (stderr, "Coverage initialized\n");)
 
-       coverage_methods = init_hashtable (&coverage_methods_mutex);
-       coverage_assemblies = init_hashtable (&coverage_assemblies_mutex);
-       coverage_classes = init_hashtable (&coverage_classes_mutex);
-       filtered_classes = init_hashtable (&filtered_classes_mutex);
-       entered_methods = init_hashtable (&entered_methods_mutex);
-       image_to_methods = init_hashtable (&image_to_methods_mutex);
+       mono_os_mutex_init (&coverage_mutex);
+       coverage_methods = mono_conc_hashtable_new (NULL, NULL);
+       coverage_assemblies = mono_conc_hashtable_new (NULL, NULL);
+       coverage_classes = mono_conc_hashtable_new (NULL, NULL);
+       filtered_classes = mono_conc_hashtable_new (NULL, NULL);
+       entered_methods = mono_conc_hashtable_new (NULL, NULL);
+       image_to_methods = mono_conc_hashtable_new (NULL, NULL);
        init_suppressed_assemblies ();
 
        coverage_initialized = TRUE;
@@ -3495,7 +3862,6 @@ log_shutdown (MonoProfiler *prof)
        }
 #endif
 
-       dump_sample_hits (prof, prof->stat_buffers);
        g_ptr_array_free (prof->sorted_sample_events, TRUE);
 
        if (TLS_GET (LogBuffer, tlsbuffer))
@@ -3516,16 +3882,19 @@ log_shutdown (MonoProfiler *prof)
        else
                fclose (prof->file);
 
-       destroy_hashtable (prof->method_table, &prof->method_table_mutex);
+       mono_conc_hashtable_destroy (prof->method_table);
+       mono_os_mutex_destroy (&prof->method_table_mutex);
 
        if (coverage_initialized) {
-               destroy_hashtable (coverage_methods, &coverage_methods_mutex);
-               destroy_hashtable (coverage_assemblies, &coverage_assemblies_mutex);
-               destroy_hashtable (coverage_classes, &coverage_classes_mutex);
-               destroy_hashtable (filtered_classes, &filtered_classes_mutex);
-               destroy_hashtable (entered_methods, &entered_methods_mutex);
-               destroy_hashtable (image_to_methods, &image_to_methods_mutex);
-               destroy_hashtable (suppressed_assemblies, &suppressed_assemblies_mutex);
+               mono_conc_hashtable_destroy (coverage_methods);
+               mono_conc_hashtable_destroy (coverage_assemblies);
+               mono_conc_hashtable_destroy (coverage_classes);
+               mono_conc_hashtable_destroy (filtered_classes);
+
+               mono_conc_hashtable_destroy (entered_methods);
+               mono_conc_hashtable_destroy (image_to_methods);
+               mono_conc_hashtable_destroy (suppressed_assemblies);
+               mono_os_mutex_destroy (&coverage_mutex);
        }
 
        free (prof);
@@ -3563,7 +3932,7 @@ new_filename (const char* filename)
                1900 + ts->tm_year, 1 + ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec);
        s_date = strlen (time_buf);
        s_pid = strlen (pid_buf);
-       d = res = malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids);
+       d = res = (char *)malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids);
        for (p = filename; *p; p++) {
                if (*p != '%') {
                        *d++ = *p;
@@ -3598,7 +3967,7 @@ extern void mono_threads_attach_tools_thread (void);
 static void*
 helper_thread (void* arg)
 {
-       MonoProfiler* prof = arg;
+       MonoProfiler* prof = (MonoProfiler *)arg;
        int command_socket;
        int len;
        char buf [64];
@@ -3669,6 +4038,7 @@ helper_thread (void* arg)
                                continue;
                        }
                        /* time to shut down */
+                       dump_sample_hits (prof, prof->stat_buffers);
                        if (thread)
                                mono_thread_detach (thread);
                        if (do_debug)
@@ -3783,7 +4153,7 @@ start_helper_thread (MonoProfiler* prof)
 static void *
 writer_thread (void *arg)
 {
-       MonoProfiler *prof = arg;
+       MonoProfiler *prof = (MonoProfiler *)arg;
 
        mono_threads_attach_tools_thread ();
 
@@ -3805,7 +4175,7 @@ writer_thread (void *arg)
                         * methods have metadata emitted before they're referenced.
                         */
                        for (guint i = 0; i < entry->methods->len; i++) {
-                               MethodInfo *info = g_ptr_array_index (entry->methods, i);
+                               MethodInfo *info = (MethodInfo *)g_ptr_array_index (entry->methods, i);
 
                                if (mono_conc_hashtable_lookup (prof->method_table, info->method))
                                        continue;
@@ -3822,19 +4192,29 @@ writer_thread (void *arg)
                                 * method lists will just be empty for the rest of the
                                 * app's lifetime.
                                 */
+                               mono_os_mutex_lock (&prof->method_table_mutex);
                                mono_conc_hashtable_insert (prof->method_table, info->method, info->method);
+                               mono_os_mutex_unlock (&prof->method_table_mutex);
 
                                char *name = mono_method_full_name (info->method, 1);
                                int nlen = strlen (name) + 1;
-                               uint64_t now = current_time ();
-
-                               method_buffer = ensure_logbuf_inner (method_buffer, 32 + nlen);
+                               void *cstart = info->ji ? mono_jit_info_get_code_start (info->ji) : NULL;
+                               int csize = info->ji ? mono_jit_info_get_code_size (info->ji) : 0;
+
+                               method_buffer = ensure_logbuf_inner (method_buffer,
+                                       EVENT_SIZE /* event */ +
+                                       LEB128_SIZE /* time */ +
+                                       LEB128_SIZE /* method */ +
+                                       LEB128_SIZE /* start */ +
+                                       LEB128_SIZE /* size */ +
+                                       nlen /* name */
+                               );
 
                                emit_byte (method_buffer, TYPE_JIT | TYPE_METHOD);
-                               emit_time (method_buffer, now);
+                               emit_time (method_buffer, info->time);
                                emit_method_inner (method_buffer, info->method);
-                               emit_ptr (method_buffer, mono_jit_info_get_code_start (info->ji));
-                               emit_value (method_buffer, mono_jit_info_get_code_size (info->ji));
+                               emit_ptr (method_buffer, cstart);
+                               emit_value (method_buffer, csize);
 
                                memcpy (method_buffer->data, name, nlen);
                                method_buffer->data += nlen;
@@ -3894,7 +4274,7 @@ create_profiler (const char *filename, GPtrArray *filters)
        MonoProfiler *prof;
        char *nf;
        int force_delete = 0;
-       prof = calloc (1, sizeof (MonoProfiler));
+       prof = (MonoProfiler *)calloc (1, sizeof (MonoProfiler));
 
        prof->command_port = command_port;
        if (filename && *filename == '-') {
@@ -3911,7 +4291,7 @@ create_profiler (const char *filename, GPtrArray *filters)
                nf = new_filename (filename);
                if (do_report) {
                        int s = strlen (nf) + 32;
-                       char *p = malloc (s);
+                       char *p = (char *)malloc (s);
                        snprintf (p, s, "|mprof-report '--out=%s' -", nf);
                        free (nf);
                        nf = p;
@@ -3964,8 +4344,8 @@ create_profiler (const char *filename, GPtrArray *filters)
 #endif
 
        mono_lock_free_queue_init (&prof->writer_queue);
-       mono_mutex_init (&prof->method_table_mutex);
-       prof->method_table = mono_conc_hashtable_new (&prof->method_table_mutex, NULL, NULL);
+       mono_os_mutex_init (&prof->method_table_mutex);
+       prof->method_table = mono_conc_hashtable_new (NULL, NULL);
 
        if (do_coverage)
                coverage_init (prof);
@@ -4024,7 +4404,7 @@ match_option (const char* p, const char *opt, char **rval)
                                } else {
                                        l = end - opt;
                                }
-                               val = malloc (l + 1);
+                               val = (char *)malloc (l + 1);
                                memcpy (val, opt, l);
                                val [l] = 0;
                                *rval = val;
@@ -4358,7 +4738,7 @@ mono_profiler_startup (const char *desc)
        mono_profiler_install_context (context_loaded, context_unloaded);
        mono_profiler_install_class (NULL, class_loaded, NULL, class_unloaded);
        mono_profiler_install_module (NULL, image_loaded, NULL, image_unloaded);
-       mono_profiler_install_assembly (NULL, assembly_loaded, NULL, assembly_unloaded);
+       mono_profiler_install_assembly (NULL, assembly_loaded, assembly_unloaded, NULL);
        mono_profiler_install_thread (thread_start, thread_end);
        mono_profiler_install_thread_name (thread_name);
        mono_profiler_install_enter_leave (method_enter, method_leave);
@@ -4376,7 +4756,7 @@ mono_profiler_startup (const char *desc)
                mono_profiler_install_statistical (mono_sample_hit);
        }
 
-       mono_profiler_set_events (events);
+       mono_profiler_set_events ((MonoProfileFlags)events);
 
        TLS_INIT (tlsbuffer);
        TLS_INIT (tlsmethodlist);