#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>
#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;
*
* 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
* [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
* [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:
struct _MethodInfo {
MonoMethod *method;
MonoJitInfo *ji;
+ uint64_t time;
};
#ifdef TLS_INIT
pstrdup (const char *s)
{
int len = strlen (s) + 1;
- char *p = malloc (len);
+ char *p = (char *)malloc (len);
memcpy (p, s, len);
return p;
}
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;
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;
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
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);
assert (logbuffer->data <= logbuffer->data_end);
}
+/*
typedef struct {
MonoMethod *method;
MonoJitInfo *found;
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 };
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);
}
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;
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);
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;
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);
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);
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);
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;
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);
{
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);
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);
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);
}
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;
}
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);
{
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");
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");
{
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");
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);
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");
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");
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 ();
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 ();
return;
register_method_local (prof, method, ji);
+
+ process_requests (prof);
}
static void
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);
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);
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);
emit_value (logbuffer, clause_num);
emit_method (prof, logbuffer, method);
EXIT_LOG (logbuffer);
+
+ process_requests (prof);
}
static void
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);
//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");
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");
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);
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");
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");
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");
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");
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");
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);
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;
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));
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 */
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]);
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);
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);
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;
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);
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 ();
/*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);
* 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++;
}
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) {
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;
item->next = agent;
}
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
}
static mono_bool
{
assert (!counters_initialized);
- mono_mutex_init (&counters_mutex);
+ mono_os_mutex_init (&counters_mutex);
counters_initialized = TRUE;
{
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;
}
}
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
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);
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;
{
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;
}
}
EXIT_LOG (logbuffer);
- safe_send (profiler, ensure_logbuf (0));
+ safe_send (profiler, logbuffer);
}
static gboolean
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)
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");
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
}
#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;
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 {
char *class_name;
const char *image_name, *method_name, *sig, *first_filename;
LogBuffer *logbuffer;
- int size = 1;
guint i;
previous_offset = 0;
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 = "";
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);
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);
emit_uvalue (logbuffer, entry->column);
EXIT_LOG (logbuffer);
- safe_send (prof, ensure_logbuf (0));
+ safe_send (prof, logbuffer);
}
method_id++;
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);
/* 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);
emit_uvalue (logbuffer, partially_covered);
EXIT_LOG (logbuffer);
- safe_send (prof, ensure_logbuf (0));
+ safe_send (prof, logbuffer);
g_free (class_name);
}
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)
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;
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);
emit_uvalue (logbuffer, partially_covered);
EXIT_LOG (logbuffer);
- safe_send (prof, ensure_logbuf (0));
+ safe_send (prof, logbuffer);
}
static void
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");)
}
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;
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];
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);
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;
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);
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);
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;
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;
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
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;
}
#endif
- dump_sample_hits (prof, prof->stat_buffers);
g_ptr_array_free (prof->sorted_sample_events, TRUE);
if (TLS_GET (LogBuffer, tlsbuffer))
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);
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;
static void*
helper_thread (void* arg)
{
- MonoProfiler* prof = arg;
+ MonoProfiler* prof = (MonoProfiler *)arg;
int command_socket;
int len;
char buf [64];
continue;
}
/* time to shut down */
+ dump_sample_hits (prof, prof->stat_buffers);
if (thread)
mono_thread_detach (thread);
if (do_debug)
static void *
writer_thread (void *arg)
{
- MonoProfiler *prof = arg;
+ MonoProfiler *prof = (MonoProfiler *)arg;
mono_threads_attach_tools_thread ();
* 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;
* 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;
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 == '-') {
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;
#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);
} else {
l = end - opt;
}
- val = malloc (l + 1);
+ val = (char *)malloc (l + 1);
memcpy (val, opt, l);
val [l] = 0;
*rval = val;
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);
mono_profiler_install_statistical (mono_sample_hit);
}
- mono_profiler_set_events (events);
+ mono_profiler_set_events ((MonoProfileFlags)events);
TLS_INIT (tlsbuffer);
TLS_INIT (tlsmethodlist);