Merge pull request #5210 from alexrp/profiler-runtime-settings
[mono.git] / mono / profiler / log.c
1 /*
2  * log.c: mono log profiler
3  *
4  * Authors:
5  *   Paolo Molaro (lupus@ximian.com)
6  *   Alex Rønne Petersen (alexrp@xamarin.com)
7  *
8  * Copyright 2010 Novell, Inc (http://www.novell.com)
9  * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
10  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11  */
12
13 #include <config.h>
14 #include <mono/metadata/assembly.h>
15 #include <mono/metadata/debug-helpers.h>
16 #include "../metadata/metadata-internals.h"
17 #include <mono/metadata/mono-config.h>
18 #include <mono/metadata/mono-gc.h>
19 #include <mono/metadata/mono-perfcounters.h>
20 #include <mono/metadata/tabledefs.h>
21 #include <mono/utils/atomic.h>
22 #include <mono/utils/hazard-pointer.h>
23 #include <mono/utils/lock-free-alloc.h>
24 #include <mono/utils/lock-free-queue.h>
25 #include <mono/utils/mono-conc-hashtable.h>
26 #include <mono/utils/mono-counters.h>
27 #include <mono/utils/mono-logger-internals.h>
28 #include <mono/utils/mono-linked-list-set.h>
29 #include <mono/utils/mono-membar.h>
30 #include <mono/utils/mono-mmap.h>
31 #include <mono/utils/mono-os-mutex.h>
32 #include <mono/utils/mono-os-semaphore.h>
33 #include <mono/utils/mono-threads.h>
34 #include <mono/utils/mono-threads-api.h>
35 #include "log.h"
36
37 #ifdef HAVE_DLFCN_H
38 #include <dlfcn.h>
39 #endif
40 #include <fcntl.h>
41 #ifdef HAVE_LINK_H
42 #include <link.h>
43 #endif
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47 #if defined(__APPLE__)
48 #include <mach/mach_time.h>
49 #endif
50 #include <netinet/in.h>
51 #ifdef HAVE_SYS_MMAN_H
52 #include <sys/mman.h>
53 #endif
54 #include <sys/socket.h>
55 #if defined (HAVE_SYS_ZLIB)
56 #include <zlib.h>
57 #endif
58
59 // Statistics for internal profiler data structures.
60 static gint32 sample_allocations_ctr,
61               buffer_allocations_ctr;
62
63 // Statistics for profiler events.
64 static gint32 sync_points_ctr,
65               heap_objects_ctr,
66               heap_starts_ctr,
67               heap_ends_ctr,
68               heap_roots_ctr,
69               gc_events_ctr,
70               gc_resizes_ctr,
71               gc_allocs_ctr,
72               gc_moves_ctr,
73               gc_handle_creations_ctr,
74               gc_handle_deletions_ctr,
75               finalize_begins_ctr,
76               finalize_ends_ctr,
77               finalize_object_begins_ctr,
78               finalize_object_ends_ctr,
79               image_loads_ctr,
80               image_unloads_ctr,
81               assembly_loads_ctr,
82               assembly_unloads_ctr,
83               class_loads_ctr,
84               class_unloads_ctr,
85               method_entries_ctr,
86               method_exits_ctr,
87               method_exception_exits_ctr,
88               method_jits_ctr,
89               code_buffers_ctr,
90               exception_throws_ctr,
91               exception_clauses_ctr,
92               monitor_events_ctr,
93               thread_starts_ctr,
94               thread_ends_ctr,
95               thread_names_ctr,
96               domain_loads_ctr,
97               domain_unloads_ctr,
98               domain_names_ctr,
99               context_loads_ctr,
100               context_unloads_ctr,
101               sample_ubins_ctr,
102               sample_usyms_ctr,
103               sample_hits_ctr,
104               counter_descriptors_ctr,
105               counter_samples_ctr,
106               perfcounter_descriptors_ctr,
107               perfcounter_samples_ctr,
108               coverage_methods_ctr,
109               coverage_statements_ctr,
110               coverage_classes_ctr,
111               coverage_assemblies_ctr;
112
113 // Pending data to be written to the log, for a single thread.
114 // Threads periodically flush their own LogBuffers by calling safe_send
115 typedef struct _LogBuffer LogBuffer;
116 struct _LogBuffer {
117         // Next (older) LogBuffer in processing queue
118         LogBuffer *next;
119
120         uint64_t time_base;
121         uint64_t last_time;
122         uintptr_t ptr_base;
123         uintptr_t method_base;
124         uintptr_t last_method;
125         uintptr_t obj_base;
126         uintptr_t thread_id;
127
128         // Bytes allocated for this LogBuffer
129         int size;
130
131         // Start of currently unused space in buffer
132         unsigned char* cursor;
133
134         // Pointer to start-of-structure-plus-size (for convenience)
135         unsigned char* buf_end;
136
137         // Start of data in buffer. Contents follow "buffer format" described above.
138         unsigned char buf [1];
139 };
140
141 typedef struct {
142         MonoLinkedListSetNode node;
143
144         // Was this thread added to the LLS?
145         gboolean attached;
146
147         // The current log buffer for this thread.
148         LogBuffer *buffer;
149
150         // Methods referenced by events in `buffer`, see `MethodInfo`.
151         GPtrArray *methods;
152
153         // Current call depth for enter/leave events.
154         int call_depth;
155
156         // Indicates whether this thread is currently writing to its `buffer`.
157         gboolean busy;
158
159         // Has this thread written a thread end event to `buffer`?
160         gboolean ended;
161
162         // Stored in `buffer_lock_state` to take the exclusive lock.
163         int small_id;
164 } MonoProfilerThread;
165
166 // Do not use these TLS macros directly unless you know what you're doing.
167
168 #ifdef HOST_WIN32
169
170 #define PROF_TLS_SET(VAL) (TlsSetValue (profiler_tls, (VAL)))
171 #define PROF_TLS_GET() ((MonoProfilerThread *) TlsGetValue (profiler_tls))
172 #define PROF_TLS_INIT() (profiler_tls = TlsAlloc ())
173 #define PROF_TLS_FREE() (TlsFree (profiler_tls))
174
175 static DWORD profiler_tls;
176
177 #elif HAVE_KW_THREAD
178
179 #define PROF_TLS_SET(VAL) (profiler_tls = (VAL))
180 #define PROF_TLS_GET() (profiler_tls)
181 #define PROF_TLS_INIT()
182 #define PROF_TLS_FREE()
183
184 static __thread MonoProfilerThread *profiler_tls;
185
186 #else
187
188 #define PROF_TLS_SET(VAL) (pthread_setspecific (profiler_tls, (VAL)))
189 #define PROF_TLS_GET() ((MonoProfilerThread *) pthread_getspecific (profiler_tls))
190 #define PROF_TLS_INIT() (pthread_key_create (&profiler_tls, NULL))
191 #define PROF_TLS_FREE() (pthread_key_delete (profiler_tls))
192
193 static pthread_key_t profiler_tls;
194
195 #endif
196
197 static uintptr_t
198 thread_id (void)
199 {
200         return (uintptr_t) mono_native_thread_id_get ();
201 }
202
203 static uintptr_t
204 process_id (void)
205 {
206 #ifdef HOST_WIN32
207         return (uintptr_t) GetCurrentProcessId ();
208 #else
209         return (uintptr_t) getpid ();
210 #endif
211 }
212
213 #define ENABLED(EVT) (log_config.effective_mask & (EVT))
214
215 /*
216  * These macros should be used when writing an event to a log buffer. They
217  * take care of a bunch of stuff that can be repetitive and error-prone, such
218  * as attaching the current thread, acquiring/releasing the buffer lock,
219  * incrementing the event counter, expanding the log buffer, etc. They also
220  * create a scope so that it's harder to leak the LogBuffer pointer, which can
221  * be problematic as the pointer is unstable when the buffer lock isn't
222  * acquired.
223  *
224  * If the calling thread is already attached, these macros will not alter its
225  * attach mode (i.e. whether it's added to the LLS). If the thread is not
226  * attached, init_thread () will be called with add_to_lls = TRUE.
227  */
228
229 #define ENTER_LOG(COUNTER, BUFFER, SIZE) \
230         do { \
231                 MonoProfilerThread *thread__ = get_thread (); \
232                 if (thread__->attached) \
233                         buffer_lock (); \
234                 g_assert (!thread__->busy && "Why are we trying to write a new event while already writing one?"); \
235                 thread__->busy = TRUE; \
236                 InterlockedIncrement ((COUNTER)); \
237                 LogBuffer *BUFFER = ensure_logbuf_unsafe (thread__, (SIZE))
238
239 #define EXIT_LOG_EXPLICIT(SEND) \
240                 thread__->busy = FALSE; \
241                 if ((SEND)) \
242                         send_log_unsafe (TRUE); \
243                 if (thread__->attached) \
244                         buffer_unlock (); \
245         } while (0)
246
247 // Pass these to EXIT_LOG_EXPLICIT () for easier reading.
248 #define DO_SEND TRUE
249 #define NO_SEND FALSE
250
251 #define EXIT_LOG EXIT_LOG_EXPLICIT (DO_SEND)
252
253 typedef struct _BinaryObject BinaryObject;
254 struct _BinaryObject {
255         BinaryObject *next;
256         void *addr;
257         char *name;
258 };
259
260 typedef struct MonoCounterAgent {
261         MonoCounter *counter;
262         // MonoCounterAgent specific data :
263         void *value;
264         size_t value_size;
265         guint32 index;
266         gboolean emitted;
267         struct MonoCounterAgent *next;
268 } MonoCounterAgent;
269
270 typedef struct _PerfCounterAgent PerfCounterAgent;
271 struct _PerfCounterAgent {
272         PerfCounterAgent *next;
273         guint32 index;
274         char *category_name;
275         char *name;
276         gint64 value;
277         gboolean emitted;
278         gboolean updated;
279         gboolean deleted;
280 };
281
282 struct _MonoProfiler {
283         MonoProfilerHandle handle;
284
285         FILE* file;
286 #if defined (HAVE_SYS_ZLIB)
287         gzFile gzfile;
288 #endif
289
290         char *args;
291         uint64_t startup_time;
292         int timer_overhead;
293
294 #ifdef __APPLE__
295         mach_timebase_info_data_t timebase_info;
296 #elif defined (HOST_WIN32)
297         LARGE_INTEGER pcounter_freq;
298 #endif
299
300         int pipe_output;
301         int command_port;
302         int server_socket;
303         int pipes [2];
304
305         MonoLinkedListSet profiler_thread_list;
306         volatile gint32 buffer_lock_state;
307         volatile gint32 buffer_lock_exclusive_intent;
308
309         volatile gint32 runtime_inited;
310         volatile gint32 in_shutdown;
311
312         MonoNativeThreadId helper_thread;
313
314         MonoNativeThreadId writer_thread;
315         volatile gint32 run_writer_thread;
316         MonoLockFreeQueue writer_queue;
317         MonoSemType writer_queue_sem;
318
319         MonoLockFreeAllocSizeClass writer_entry_size_class;
320         MonoLockFreeAllocator writer_entry_allocator;
321
322         MonoConcurrentHashTable *method_table;
323         mono_mutex_t method_table_mutex;
324
325         MonoNativeThreadId dumper_thread;
326         volatile gint32 run_dumper_thread;
327         MonoLockFreeQueue dumper_queue;
328         MonoSemType dumper_queue_sem;
329
330         MonoLockFreeAllocSizeClass sample_size_class;
331         MonoLockFreeAllocator sample_allocator;
332         MonoLockFreeQueue sample_reuse_queue;
333
334         BinaryObject *binary_objects;
335
336         volatile gint32 heapshot_requested;
337         guint64 gc_count;
338         guint64 last_hs_time;
339         gboolean do_heap_walk;
340
341         mono_mutex_t counters_mutex;
342         MonoCounterAgent *counters;
343         PerfCounterAgent *perfcounters;
344         guint32 counters_index;
345
346         mono_mutex_t coverage_mutex;
347         GPtrArray *coverage_data;
348
349         GPtrArray *coverage_filters;
350         MonoConcurrentHashTable *coverage_filtered_classes;
351         MonoConcurrentHashTable *coverage_suppressed_assemblies;
352
353         MonoConcurrentHashTable *coverage_methods;
354         MonoConcurrentHashTable *coverage_assemblies;
355         MonoConcurrentHashTable *coverage_classes;
356
357         MonoConcurrentHashTable *coverage_image_to_methods;
358
359         guint32 coverage_previous_offset;
360         guint32 coverage_method_id;
361 };
362
363 static ProfilerConfig log_config;
364 static struct _MonoProfiler log_profiler;
365
366 typedef struct {
367         MonoLockFreeQueueNode node;
368         GPtrArray *methods;
369         LogBuffer *buffer;
370 } WriterQueueEntry;
371
372 #define WRITER_ENTRY_BLOCK_SIZE (mono_pagesize ())
373
374 typedef struct {
375         MonoMethod *method;
376         MonoJitInfo *ji;
377         uint64_t time;
378 } MethodInfo;
379
380 #define TICKS_PER_SEC 1000000000LL
381
382 static uint64_t
383 current_time (void)
384 {
385 #ifdef __APPLE__
386         uint64_t time = mach_absolute_time ();
387
388         time *= log_profiler.timebase_info.numer;
389         time /= log_profiler.timebase_info.denom;
390
391         return time;
392 #elif defined (HOST_WIN32)
393         LARGE_INTEGER value;
394
395         QueryPerformanceCounter (&value);
396
397         return value.QuadPart * TICKS_PER_SEC / log_profiler.pcounter_freq.QuadPart;
398 #elif defined (CLOCK_MONOTONIC)
399         struct timespec tspec;
400
401         clock_gettime (CLOCK_MONOTONIC, &tspec);
402
403         return ((uint64_t) tspec.tv_sec * TICKS_PER_SEC + tspec.tv_nsec);
404 #else
405         struct timeval tv;
406
407         gettimeofday (&tv, NULL);
408
409         return ((uint64_t) tv.tv_sec * TICKS_PER_SEC + tv.tv_usec * 1000);
410 #endif
411 }
412
413 static void
414 init_time (void)
415 {
416 #ifdef __APPLE__
417         mach_timebase_info (&log_profiler.timebase_info);
418 #elif defined (HOST_WIN32)
419         QueryPerformanceFrequency (&log_profiler.pcounter_freq);
420 #endif
421
422         uint64_t time_start = current_time ();
423
424         for (int i = 0; i < 256; ++i)
425                 current_time ();
426
427         uint64_t time_end = current_time ();
428
429         log_profiler.timer_overhead = (time_end - time_start) / 256;
430 }
431
432 static char*
433 pstrdup (const char *s)
434 {
435         int len = strlen (s) + 1;
436         char *p = (char *) g_malloc (len);
437         memcpy (p, s, len);
438         return p;
439 }
440
441 #define BUFFER_SIZE (4096 * 16)
442
443 /* Worst-case size in bytes of a 64-bit value encoded with LEB128. */
444 #define LEB128_SIZE 10
445
446 /* Size of a value encoded as a single byte. */
447 #undef BYTE_SIZE // mach/i386/vm_param.h on OS X defines this to 8, but it isn't used for anything.
448 #define BYTE_SIZE 1
449
450 /* Size in bytes of the event prefix (ID + time). */
451 #define EVENT_SIZE (BYTE_SIZE + LEB128_SIZE)
452
453 static void *
454 alloc_buffer (int size)
455 {
456         return mono_valloc (NULL, size, MONO_MMAP_READ | MONO_MMAP_WRITE | MONO_MMAP_ANON | MONO_MMAP_PRIVATE, MONO_MEM_ACCOUNT_PROFILER);
457 }
458
459 static void
460 free_buffer (void *buf, int size)
461 {
462         mono_vfree (buf, size, MONO_MEM_ACCOUNT_PROFILER);
463 }
464
465 static LogBuffer*
466 create_buffer (uintptr_t tid, int bytes)
467 {
468         LogBuffer* buf = (LogBuffer *) alloc_buffer (MAX (BUFFER_SIZE, bytes));
469
470         InterlockedIncrement (&buffer_allocations_ctr);
471
472         buf->size = BUFFER_SIZE;
473         buf->time_base = current_time ();
474         buf->last_time = buf->time_base;
475         buf->buf_end = (unsigned char *) buf + buf->size;
476         buf->cursor = buf->buf;
477         buf->thread_id = tid;
478
479         return buf;
480 }
481
482 /*
483  * Must be called with the reader lock held if thread is the current thread, or
484  * the exclusive lock if thread is a different thread. However, if thread is
485  * the current thread, and init_thread () was called with add_to_lls = FALSE,
486  * then no locking is necessary.
487  */
488 static void
489 init_buffer_state (MonoProfilerThread *thread)
490 {
491         thread->buffer = create_buffer (thread->node.key, 0);
492         thread->methods = NULL;
493 }
494
495 static void
496 clear_hazard_pointers (MonoThreadHazardPointers *hp)
497 {
498         mono_hazard_pointer_clear (hp, 0);
499         mono_hazard_pointer_clear (hp, 1);
500         mono_hazard_pointer_clear (hp, 2);
501 }
502
503 static MonoProfilerThread *
504 init_thread (gboolean add_to_lls)
505 {
506         MonoProfilerThread *thread = PROF_TLS_GET ();
507
508         /*
509          * Sometimes we may try to initialize a thread twice. One example is the
510          * main thread: We initialize it when setting up the profiler, but we will
511          * also get a thread_start () callback for it. Another example is when
512          * attaching new threads to the runtime: We may get a gc_alloc () callback
513          * for that thread's thread object (where we initialize it), soon followed
514          * by a thread_start () callback.
515          *
516          * These cases are harmless anyhow. Just return if we've already done the
517          * initialization work.
518          */
519         if (thread)
520                 return thread;
521
522         thread = g_malloc (sizeof (MonoProfilerThread));
523         thread->node.key = thread_id ();
524         thread->attached = add_to_lls;
525         thread->call_depth = 0;
526         thread->busy = 0;
527         thread->ended = FALSE;
528
529         init_buffer_state (thread);
530
531         thread->small_id = mono_thread_info_register_small_id ();
532
533         /*
534          * Some internal profiler threads don't need to be cleaned up
535          * by the main thread on shutdown.
536          */
537         if (add_to_lls) {
538                 MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
539                 g_assert (mono_lls_insert (&log_profiler.profiler_thread_list, hp, &thread->node) && "Why can't we insert the thread in the LLS?");
540                 clear_hazard_pointers (hp);
541         }
542
543         PROF_TLS_SET (thread);
544
545         return thread;
546 }
547
548 // Only valid if init_thread () was called with add_to_lls = FALSE.
549 static void
550 deinit_thread (MonoProfilerThread *thread)
551 {
552         g_assert (!thread->attached && "Why are we manually freeing an attached thread?");
553
554         g_free (thread);
555         PROF_TLS_SET (NULL);
556 }
557
558 static MonoProfilerThread *
559 get_thread (void)
560 {
561         return init_thread (TRUE);
562 }
563
564 // Only valid if init_thread () was called with add_to_lls = FALSE.
565 static LogBuffer *
566 ensure_logbuf_unsafe (MonoProfilerThread *thread, int bytes)
567 {
568         LogBuffer *old = thread->buffer;
569
570         if (old->cursor + bytes < old->buf_end)
571                 return old;
572
573         LogBuffer *new_ = create_buffer (thread->node.key, bytes);
574         new_->next = old;
575         thread->buffer = new_;
576
577         return new_;
578 }
579
580 /*
581  * This is a reader/writer spin lock of sorts used to protect log buffers.
582  * When a thread modifies its own log buffer, it increments the reader
583  * count. When a thread wants to access log buffers of other threads, it
584  * takes the exclusive lock.
585  *
586  * `buffer_lock_state` holds the reader count in its lower 16 bits, and
587  * the small ID of the thread currently holding the exclusive (writer)
588  * lock in its upper 16 bits. Both can be zero. It's important that the
589  * whole lock state is a single word that can be read/written atomically
590  * to avoid race conditions where there could end up being readers while
591  * the writer lock is held.
592  *
593  * The lock is writer-biased. When a thread wants to take the exclusive
594  * lock, it increments `buffer_lock_exclusive_intent` which will make new
595  * readers spin until it's back to zero, then takes the exclusive lock
596  * once the reader count has reached zero. After releasing the exclusive
597  * lock, it decrements `buffer_lock_exclusive_intent`, which, when it
598  * reaches zero again, allows readers to increment the reader count.
599  *
600  * The writer bias is necessary because we take the exclusive lock in
601  * `gc_event ()` during STW. If the writer bias was not there, and a
602  * program had a large number of threads, STW-induced pauses could be
603  * significantly longer than they have to be. Also, we emit periodic
604  * sync points from the helper thread, which requires taking the
605  * exclusive lock, and we need those to arrive with a reasonably
606  * consistent frequency so that readers don't have to queue up too many
607  * events between sync points.
608  *
609  * The lock does not support recursion.
610  */
611
612 static void
613 buffer_lock (void)
614 {
615         /*
616          * If the thread holding the exclusive lock tries to modify the
617          * reader count, just make it a no-op. This way, we also avoid
618          * invoking the GC safe point macros below, which could break if
619          * done from a thread that is currently the initiator of STW.
620          *
621          * In other words, we rely on the fact that the GC thread takes
622          * the exclusive lock in the gc_event () callback when the world
623          * is about to stop.
624          */
625         if (InterlockedRead (&log_profiler.buffer_lock_state) != get_thread ()->small_id << 16) {
626                 MONO_ENTER_GC_SAFE;
627
628                 gint32 old, new_;
629
630                 do {
631                 restart:
632                         // Hold off if a thread wants to take the exclusive lock.
633                         while (InterlockedRead (&log_profiler.buffer_lock_exclusive_intent))
634                                 mono_thread_info_yield ();
635
636                         old = InterlockedRead (&log_profiler.buffer_lock_state);
637
638                         // Is a thread holding the exclusive lock?
639                         if (old >> 16) {
640                                 mono_thread_info_yield ();
641                                 goto restart;
642                         }
643
644                         new_ = old + 1;
645                 } while (InterlockedCompareExchange (&log_profiler.buffer_lock_state, new_, old) != old);
646
647                 MONO_EXIT_GC_SAFE;
648         }
649
650         mono_memory_barrier ();
651 }
652
653 static void
654 buffer_unlock (void)
655 {
656         mono_memory_barrier ();
657
658         gint32 state = InterlockedRead (&log_profiler.buffer_lock_state);
659
660         // See the comment in buffer_lock ().
661         if (state == PROF_TLS_GET ()->small_id << 16)
662                 return;
663
664         g_assert (state && "Why are we decrementing a zero reader count?");
665         g_assert (!(state >> 16) && "Why is the exclusive lock held?");
666
667         InterlockedDecrement (&log_profiler.buffer_lock_state);
668 }
669
670 static void
671 buffer_lock_excl (void)
672 {
673         gint32 new_ = get_thread ()->small_id << 16;
674
675         g_assert (InterlockedRead (&log_profiler.buffer_lock_state) != new_ && "Why are we taking the exclusive lock twice?");
676
677         InterlockedIncrement (&log_profiler.buffer_lock_exclusive_intent);
678
679         MONO_ENTER_GC_SAFE;
680
681         while (InterlockedCompareExchange (&log_profiler.buffer_lock_state, new_, 0))
682                 mono_thread_info_yield ();
683
684         MONO_EXIT_GC_SAFE;
685
686         mono_memory_barrier ();
687 }
688
689 static void
690 buffer_unlock_excl (void)
691 {
692         mono_memory_barrier ();
693
694         gint32 state = InterlockedRead (&log_profiler.buffer_lock_state);
695         gint32 excl = state >> 16;
696
697         g_assert (excl && "Why is the exclusive lock not held?");
698         g_assert (excl == PROF_TLS_GET ()->small_id && "Why does another thread hold the exclusive lock?");
699         g_assert (!(state & 0xFFFF) && "Why are there readers when the exclusive lock is held?");
700
701         InterlockedWrite (&log_profiler.buffer_lock_state, 0);
702         InterlockedDecrement (&log_profiler.buffer_lock_exclusive_intent);
703 }
704
705 static void
706 encode_uleb128 (uint64_t value, uint8_t *buf, uint8_t **endbuf)
707 {
708         uint8_t *p = buf;
709
710         do {
711                 uint8_t b = value & 0x7f;
712                 value >>= 7;
713
714                 if (value != 0) /* more bytes to come */
715                         b |= 0x80;
716
717                 *p ++ = b;
718         } while (value);
719
720         *endbuf = p;
721 }
722
723 static void
724 encode_sleb128 (intptr_t value, uint8_t *buf, uint8_t **endbuf)
725 {
726         int more = 1;
727         int negative = (value < 0);
728         unsigned int size = sizeof (intptr_t) * 8;
729         uint8_t byte;
730         uint8_t *p = buf;
731
732         while (more) {
733                 byte = value & 0x7f;
734                 value >>= 7;
735
736                 /* the following is unnecessary if the
737                  * implementation of >>= uses an arithmetic rather
738                  * than logical shift for a signed left operand
739                  */
740                 if (negative)
741                         /* sign extend */
742                         value |= - ((intptr_t) 1 <<(size - 7));
743
744                 /* sign bit of byte is second high order bit (0x40) */
745                 if ((value == 0 && !(byte & 0x40)) ||
746                     (value == -1 && (byte & 0x40)))
747                         more = 0;
748                 else
749                         byte |= 0x80;
750
751                 *p ++= byte;
752         }
753
754         *endbuf = p;
755 }
756
757 static void
758 emit_byte (LogBuffer *logbuffer, int value)
759 {
760         logbuffer->cursor [0] = value;
761         logbuffer->cursor++;
762
763         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
764 }
765
766 static void
767 emit_value (LogBuffer *logbuffer, int value)
768 {
769         encode_uleb128 (value, logbuffer->cursor, &logbuffer->cursor);
770
771         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
772 }
773
774 static void
775 emit_time (LogBuffer *logbuffer, uint64_t value)
776 {
777         uint64_t tdiff = value - logbuffer->last_time;
778         encode_uleb128 (tdiff, logbuffer->cursor, &logbuffer->cursor);
779         logbuffer->last_time = value;
780
781         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
782 }
783
784 static void
785 emit_event_time (LogBuffer *logbuffer, int event, uint64_t time)
786 {
787         emit_byte (logbuffer, event);
788         emit_time (logbuffer, time);
789 }
790
791 static void
792 emit_event (LogBuffer *logbuffer, int event)
793 {
794         emit_event_time (logbuffer, event, current_time ());
795 }
796
797 static void
798 emit_svalue (LogBuffer *logbuffer, int64_t value)
799 {
800         encode_sleb128 (value, logbuffer->cursor, &logbuffer->cursor);
801
802         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
803 }
804
805 static void
806 emit_uvalue (LogBuffer *logbuffer, uint64_t value)
807 {
808         encode_uleb128 (value, logbuffer->cursor, &logbuffer->cursor);
809
810         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
811 }
812
813 static void
814 emit_ptr (LogBuffer *logbuffer, const void *ptr)
815 {
816         if (!logbuffer->ptr_base)
817                 logbuffer->ptr_base = (uintptr_t) ptr;
818
819         emit_svalue (logbuffer, (intptr_t) ptr - logbuffer->ptr_base);
820
821         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
822 }
823
824 static void
825 emit_method_inner (LogBuffer *logbuffer, void *method)
826 {
827         if (!logbuffer->method_base) {
828                 logbuffer->method_base = (intptr_t) method;
829                 logbuffer->last_method = (intptr_t) method;
830         }
831
832         encode_sleb128 ((intptr_t) ((char *) method - (char *) logbuffer->last_method), logbuffer->cursor, &logbuffer->cursor);
833         logbuffer->last_method = (intptr_t) method;
834
835         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
836 }
837
838 // The reader lock must be held.
839 static void
840 register_method_local (MonoMethod *method, MonoJitInfo *ji)
841 {
842         MonoProfilerThread *thread = get_thread ();
843
844         if (!mono_conc_hashtable_lookup (log_profiler.method_table, method)) {
845                 MethodInfo *info = (MethodInfo *) g_malloc (sizeof (MethodInfo));
846
847                 info->method = method;
848                 info->ji = ji;
849                 info->time = current_time ();
850
851                 GPtrArray *arr = thread->methods ? thread->methods : (thread->methods = g_ptr_array_new ());
852                 g_ptr_array_add (arr, info);
853         }
854 }
855
856 static void
857 emit_method (LogBuffer *logbuffer, MonoMethod *method)
858 {
859         register_method_local (method, NULL);
860         emit_method_inner (logbuffer, method);
861 }
862
863 static void
864 emit_obj (LogBuffer *logbuffer, void *ptr)
865 {
866         if (!logbuffer->obj_base)
867                 logbuffer->obj_base = (uintptr_t) ptr >> 3;
868
869         emit_svalue (logbuffer, ((uintptr_t) ptr >> 3) - logbuffer->obj_base);
870
871         g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?");
872 }
873
874 static void
875 emit_string (LogBuffer *logbuffer, const char *str, size_t size)
876 {
877         size_t i = 0;
878         if (str) {
879                 for (; i < size; i++) {
880                         if (str[i] == '\0')
881                                 break;
882                         emit_byte (logbuffer, str [i]);
883                 }
884         }
885         emit_byte (logbuffer, '\0');
886 }
887
888 static void
889 emit_double (LogBuffer *logbuffer, double value)
890 {
891         int i;
892         unsigned char buffer[8];
893         memcpy (buffer, &value, 8);
894 #if G_BYTE_ORDER == G_BIG_ENDIAN
895         for (i = 7; i >= 0; i--)
896 #else
897         for (i = 0; i < 8; i++)
898 #endif
899                 emit_byte (logbuffer, buffer[i]);
900 }
901
902 static char*
903 write_int16 (char *buf, int32_t value)
904 {
905         int i;
906         for (i = 0; i < 2; ++i) {
907                 buf [i] = value;
908                 value >>= 8;
909         }
910         return buf + 2;
911 }
912
913 static char*
914 write_int32 (char *buf, int32_t value)
915 {
916         int i;
917         for (i = 0; i < 4; ++i) {
918                 buf [i] = value;
919                 value >>= 8;
920         }
921         return buf + 4;
922 }
923
924 static char*
925 write_int64 (char *buf, int64_t value)
926 {
927         int i;
928         for (i = 0; i < 8; ++i) {
929                 buf [i] = value;
930                 value >>= 8;
931         }
932         return buf + 8;
933 }
934
935 static char *
936 write_header_string (char *p, const char *str)
937 {
938         size_t len = strlen (str) + 1;
939
940         p = write_int32 (p, len);
941         strcpy (p, str);
942
943         return p + len;
944 }
945
946 static void
947 dump_header (void)
948 {
949         const char *args = log_profiler.args;
950         const char *arch = mono_config_get_cpu ();
951         const char *os = mono_config_get_os ();
952
953         char *hbuf = g_malloc (
954                 sizeof (gint32) /* header id */ +
955                 sizeof (gint8) /* major version */ +
956                 sizeof (gint8) /* minor version */ +
957                 sizeof (gint8) /* data version */ +
958                 sizeof (gint8) /* word size */ +
959                 sizeof (gint64) /* startup time */ +
960                 sizeof (gint32) /* timer overhead */ +
961                 sizeof (gint32) /* flags */ +
962                 sizeof (gint32) /* process id */ +
963                 sizeof (gint16) /* command port */ +
964                 sizeof (gint32) + strlen (args) + 1 /* arguments */ +
965                 sizeof (gint32) + strlen (arch) + 1 /* architecture */ +
966                 sizeof (gint32) + strlen (os) + 1 /* operating system */
967         );
968         char *p = hbuf;
969
970         p = write_int32 (p, LOG_HEADER_ID);
971         *p++ = LOG_VERSION_MAJOR;
972         *p++ = LOG_VERSION_MINOR;
973         *p++ = LOG_DATA_VERSION;
974         *p++ = sizeof (void *);
975         p = write_int64 (p, ((uint64_t) time (NULL)) * 1000);
976         p = write_int32 (p, log_profiler.timer_overhead);
977         p = write_int32 (p, 0); /* flags */
978         p = write_int32 (p, process_id ());
979         p = write_int16 (p, log_profiler.command_port);
980         p = write_header_string (p, args);
981         p = write_header_string (p, arch);
982         p = write_header_string (p, os);
983
984 #if defined (HAVE_SYS_ZLIB)
985         if (log_profiler.gzfile) {
986                 gzwrite (log_profiler.gzfile, hbuf, p - hbuf);
987         } else
988 #endif
989         {
990                 fwrite (hbuf, p - hbuf, 1, log_profiler.file);
991                 fflush (log_profiler.file);
992         }
993
994         g_free (hbuf);
995 }
996
997 /*
998  * Must be called with the reader lock held if thread is the current thread, or
999  * the exclusive lock if thread is a different thread. However, if thread is
1000  * the current thread, and init_thread () was called with add_to_lls = FALSE,
1001  * then no locking is necessary.
1002  */
1003 static void
1004 send_buffer (MonoProfilerThread *thread)
1005 {
1006         WriterQueueEntry *entry = mono_lock_free_alloc (&log_profiler.writer_entry_allocator);
1007         entry->methods = thread->methods;
1008         entry->buffer = thread->buffer;
1009
1010         mono_lock_free_queue_node_init (&entry->node, FALSE);
1011
1012         mono_lock_free_queue_enqueue (&log_profiler.writer_queue, &entry->node);
1013         mono_os_sem_post (&log_profiler.writer_queue_sem);
1014 }
1015
1016 static void
1017 free_thread (gpointer p)
1018 {
1019         MonoProfilerThread *thread = p;
1020
1021         if (!thread->ended) {
1022                 /*
1023                  * The thread is being cleaned up by the main thread during
1024                  * shutdown. This typically happens for internal runtime
1025                  * threads. We need to synthesize a thread end event.
1026                  */
1027
1028                 InterlockedIncrement (&thread_ends_ctr);
1029
1030                 LogBuffer *buf = ensure_logbuf_unsafe (thread,
1031                         EVENT_SIZE /* event */ +
1032                         BYTE_SIZE /* type */ +
1033                         LEB128_SIZE /* tid */
1034                 );
1035
1036                 emit_event (buf, TYPE_END_UNLOAD | TYPE_METADATA);
1037                 emit_byte (buf, TYPE_THREAD);
1038                 emit_ptr (buf, (void *) thread->node.key);
1039         }
1040
1041         send_buffer (thread);
1042
1043         g_free (thread);
1044 }
1045
1046 static void
1047 remove_thread (MonoProfilerThread *thread)
1048 {
1049         MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
1050
1051         if (mono_lls_remove (&log_profiler.profiler_thread_list, hp, &thread->node))
1052                 mono_thread_hazardous_try_free (thread, free_thread);
1053
1054         clear_hazard_pointers (hp);
1055 }
1056
1057 static void
1058 dump_buffer (LogBuffer *buf)
1059 {
1060         char hbuf [128];
1061         char *p = hbuf;
1062
1063         if (buf->next)
1064                 dump_buffer (buf->next);
1065
1066         if (buf->cursor - buf->buf) {
1067                 p = write_int32 (p, BUF_ID);
1068                 p = write_int32 (p, buf->cursor - buf->buf);
1069                 p = write_int64 (p, buf->time_base);
1070                 p = write_int64 (p, buf->ptr_base);
1071                 p = write_int64 (p, buf->obj_base);
1072                 p = write_int64 (p, buf->thread_id);
1073                 p = write_int64 (p, buf->method_base);
1074
1075 #if defined (HAVE_SYS_ZLIB)
1076                 if (log_profiler.gzfile) {
1077                         gzwrite (log_profiler.gzfile, hbuf, p - hbuf);
1078                         gzwrite (log_profiler.gzfile, buf->buf, buf->cursor - buf->buf);
1079                 } else
1080 #endif
1081                 {
1082                         fwrite (hbuf, p - hbuf, 1, log_profiler.file);
1083                         fwrite (buf->buf, buf->cursor - buf->buf, 1, log_profiler.file);
1084                         fflush (log_profiler.file);
1085                 }
1086         }
1087
1088         free_buffer (buf, buf->size);
1089 }
1090
1091 static void
1092 dump_buffer_threadless (LogBuffer *buf)
1093 {
1094         for (LogBuffer *iter = buf; iter; iter = iter->next)
1095                 iter->thread_id = 0;
1096
1097         dump_buffer (buf);
1098 }
1099
1100 // Only valid if init_thread () was called with add_to_lls = FALSE.
1101 static void
1102 send_log_unsafe (gboolean if_needed)
1103 {
1104         MonoProfilerThread *thread = PROF_TLS_GET ();
1105
1106         if (!if_needed || (if_needed && thread->buffer->next)) {
1107                 if (!thread->attached)
1108                         for (LogBuffer *iter = thread->buffer; iter; iter = iter->next)
1109                                 iter->thread_id = 0;
1110
1111                 send_buffer (thread);
1112                 init_buffer_state (thread);
1113         }
1114 }
1115
1116 // Assumes that the exclusive lock is held.
1117 static void
1118 sync_point_flush (void)
1119 {
1120         g_assert (InterlockedRead (&log_profiler.buffer_lock_state) == PROF_TLS_GET ()->small_id << 16 && "Why don't we hold the exclusive lock?");
1121
1122         MONO_LLS_FOREACH_SAFE (&log_profiler.profiler_thread_list, MonoProfilerThread, thread) {
1123                 g_assert (thread->attached && "Why is a thread in the LLS not attached?");
1124
1125                 send_buffer (thread);
1126                 init_buffer_state (thread);
1127         } MONO_LLS_FOREACH_SAFE_END
1128 }
1129
1130 // Assumes that the exclusive lock is held.
1131 static void
1132 sync_point_mark (MonoProfilerSyncPointType type)
1133 {
1134         g_assert (InterlockedRead (&log_profiler.buffer_lock_state) == PROF_TLS_GET ()->small_id << 16 && "Why don't we hold the exclusive lock?");
1135
1136         ENTER_LOG (&sync_points_ctr, logbuffer,
1137                 EVENT_SIZE /* event */ +
1138                 LEB128_SIZE /* type */
1139         );
1140
1141         emit_event (logbuffer, TYPE_META | TYPE_SYNC_POINT);
1142         emit_byte (logbuffer, type);
1143
1144         EXIT_LOG_EXPLICIT (NO_SEND);
1145
1146         send_log_unsafe (FALSE);
1147 }
1148
1149 // Assumes that the exclusive lock is held.
1150 static void
1151 sync_point (MonoProfilerSyncPointType type)
1152 {
1153         sync_point_flush ();
1154         sync_point_mark (type);
1155 }
1156
1157 static int
1158 gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, uintptr_t *offsets, void *data)
1159 {
1160         /* account for object alignment in the heap */
1161         size += 7;
1162         size &= ~7;
1163
1164         ENTER_LOG (&heap_objects_ctr, logbuffer,
1165                 EVENT_SIZE /* event */ +
1166                 LEB128_SIZE /* obj */ +
1167                 LEB128_SIZE /* klass */ +
1168                 LEB128_SIZE /* size */ +
1169                 LEB128_SIZE /* num */ +
1170                 num * (
1171                         LEB128_SIZE /* offset */ +
1172                         LEB128_SIZE /* ref */
1173                 )
1174         );
1175
1176         emit_event (logbuffer, TYPE_HEAP_OBJECT | TYPE_HEAP);
1177         emit_obj (logbuffer, obj);
1178         emit_ptr (logbuffer, klass);
1179         emit_value (logbuffer, size);
1180         emit_value (logbuffer, num);
1181
1182         uintptr_t last_offset = 0;
1183
1184         for (int i = 0; i < num; ++i) {
1185                 emit_value (logbuffer, offsets [i] - last_offset);
1186                 last_offset = offsets [i];
1187                 emit_obj (logbuffer, refs [i]);
1188         }
1189
1190         EXIT_LOG;
1191
1192         return 0;
1193 }
1194
1195 static void
1196 gc_roots (MonoProfiler *prof, MonoObject *const *objects, const MonoProfilerGCRootType *root_types, const uintptr_t *extra_info, uint64_t num)
1197 {
1198         ENTER_LOG (&heap_roots_ctr, logbuffer,
1199                 EVENT_SIZE /* event */ +
1200                 LEB128_SIZE /* num */ +
1201                 LEB128_SIZE /* collections */ +
1202                 num * (
1203                         LEB128_SIZE /* object */ +
1204                         LEB128_SIZE /* root type */ +
1205                         LEB128_SIZE /* extra info */
1206                 )
1207         );
1208
1209         emit_event (logbuffer, TYPE_HEAP_ROOT | TYPE_HEAP);
1210         emit_value (logbuffer, num);
1211         emit_value (logbuffer, mono_gc_collection_count (mono_gc_max_generation ()));
1212
1213         for (int i = 0; i < num; ++i) {
1214                 emit_obj (logbuffer, objects [i]);
1215                 emit_byte (logbuffer, root_types [i]);
1216                 emit_value (logbuffer, extra_info [i]);
1217         }
1218
1219         EXIT_LOG;
1220 }
1221
1222
1223 static void
1224 trigger_on_demand_heapshot (void)
1225 {
1226         if (InterlockedRead (&log_profiler.heapshot_requested))
1227                 mono_gc_collect (mono_gc_max_generation ());
1228 }
1229
1230 #define ALL_GC_EVENTS_MASK (PROFLOG_GC_EVENTS | PROFLOG_GC_MOVE_EVENTS | PROFLOG_GC_ROOT_EVENTS)
1231
1232 static void
1233 gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation)
1234 {
1235         if (ENABLED (PROFLOG_GC_EVENTS)) {
1236                 ENTER_LOG (&gc_events_ctr, logbuffer,
1237                         EVENT_SIZE /* event */ +
1238                         BYTE_SIZE /* gc event */ +
1239                         BYTE_SIZE /* generation */
1240                 );
1241
1242                 emit_event (logbuffer, TYPE_GC_EVENT | TYPE_GC);
1243                 emit_byte (logbuffer, ev);
1244                 emit_byte (logbuffer, generation);
1245
1246                 EXIT_LOG;
1247         }
1248
1249         switch (ev) {
1250         case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED:
1251                 switch (log_config.hs_mode) {
1252                 case MONO_PROFILER_HEAPSHOT_NONE:
1253                         log_profiler.do_heap_walk = FALSE;
1254                         break;
1255                 case MONO_PROFILER_HEAPSHOT_MAJOR:
1256                         log_profiler.do_heap_walk = generation == mono_gc_max_generation ();
1257                         break;
1258                 case MONO_PROFILER_HEAPSHOT_ON_DEMAND:
1259                         log_profiler.do_heap_walk = InterlockedRead (&log_profiler.heapshot_requested);
1260                         break;
1261                 case MONO_PROFILER_HEAPSHOT_X_GC:
1262                         log_profiler.do_heap_walk = !(log_profiler.gc_count % log_config.hs_freq_gc);
1263                         break;
1264                 case MONO_PROFILER_HEAPSHOT_X_MS:
1265                         log_profiler.do_heap_walk = (current_time () - log_profiler.last_hs_time) / 1000 * 1000 >= log_config.hs_freq_ms;
1266                         break;
1267                 default:
1268                         g_assert_not_reached ();
1269                 }
1270
1271                 /*
1272                  * heapshot_requested is set either because on-demand heapshot is
1273                  * enabled and a heapshot was triggered, or because we're doing a
1274                  * shutdown heapshot. In the latter case, we won't check it in the
1275                  * switch above, so check it here and override any decision we made
1276                  * above.
1277                  */
1278                 if (InterlockedRead (&log_profiler.heapshot_requested))
1279                         log_profiler.do_heap_walk = TRUE;
1280
1281                 if (ENABLED (PROFLOG_GC_ROOT_EVENTS) && log_profiler.do_heap_walk)
1282                         mono_profiler_set_gc_roots_callback (log_profiler.handle, gc_roots);
1283
1284                 /*
1285                  * Ensure that no thread can be in the middle of writing to
1286                  * a buffer when the world stops...
1287                  */
1288                 buffer_lock_excl ();
1289
1290                 break;
1291         case MONO_GC_EVENT_POST_STOP_WORLD:
1292                 /*
1293                  * ... So that we now have a consistent view of all buffers.
1294                  * This allows us to flush them. We need to do this because
1295                  * they may contain object allocation events that need to be
1296                  * committed to the log file before any object move events
1297                  * that will be produced during this GC.
1298                  */
1299                 if (ENABLED (ALL_GC_EVENTS_MASK))
1300                         sync_point (SYNC_POINT_WORLD_STOP);
1301
1302                 // Surround heapshots with HEAP_START/HEAP_END events.
1303                 if (log_profiler.do_heap_walk) {
1304                         ENTER_LOG (&heap_starts_ctr, logbuffer,
1305                                 EVENT_SIZE /* event */
1306                         );
1307
1308                         emit_event (logbuffer, TYPE_HEAP_START | TYPE_HEAP);
1309
1310                         EXIT_LOG;
1311                 }
1312
1313                 break;
1314         case MONO_GC_EVENT_START:
1315                 if (generation == mono_gc_max_generation ())
1316                         log_profiler.gc_count++;
1317
1318                 break;
1319         case MONO_GC_EVENT_PRE_START_WORLD:
1320                 mono_profiler_set_gc_roots_callback (log_profiler.handle, NULL);
1321
1322                 if (log_profiler.do_heap_walk) {
1323                         mono_gc_walk_heap (0, gc_reference, NULL);
1324
1325                         ENTER_LOG (&heap_ends_ctr, logbuffer,
1326                                 EVENT_SIZE /* event */
1327                         );
1328
1329                         emit_event (logbuffer, TYPE_HEAP_END | TYPE_HEAP);
1330
1331                         EXIT_LOG;
1332
1333                         log_profiler.do_heap_walk = FALSE;
1334                         log_profiler.last_hs_time = current_time ();
1335
1336                         InterlockedWrite (&log_profiler.heapshot_requested, 0);
1337                 }
1338
1339                 /*
1340                  * Similarly, we must now make sure that any object moves
1341                  * written to the GC thread's buffer are flushed. Otherwise,
1342                  * object allocation events for certain addresses could come
1343                  * after the move events that made those addresses available.
1344                  */
1345                 if (ENABLED (ALL_GC_EVENTS_MASK))
1346                         sync_point_mark (SYNC_POINT_WORLD_START);
1347
1348                 break;
1349         case MONO_GC_EVENT_POST_START_WORLD_UNLOCKED:
1350                 /*
1351                  * Finally, it is safe to allow other threads to write to
1352                  * their buffers again.
1353                  */
1354                 buffer_unlock_excl ();
1355
1356                 break;
1357         default:
1358                 break;
1359         }
1360 }
1361
1362 static void
1363 gc_resize (MonoProfiler *profiler, uintptr_t new_size)
1364 {
1365         ENTER_LOG (&gc_resizes_ctr, logbuffer,
1366                 EVENT_SIZE /* event */ +
1367                 LEB128_SIZE /* new size */
1368         );
1369
1370         emit_event (logbuffer, TYPE_GC_RESIZE | TYPE_GC);
1371         emit_value (logbuffer, new_size);
1372
1373         EXIT_LOG;
1374 }
1375
1376 typedef struct {
1377         int count;
1378         MonoMethod* methods [MAX_FRAMES];
1379         int32_t il_offsets [MAX_FRAMES];
1380         int32_t native_offsets [MAX_FRAMES];
1381 } FrameData;
1382
1383 static mono_bool
1384 walk_stack (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data)
1385 {
1386         FrameData *frame = (FrameData *)data;
1387         if (method && frame->count < log_config.num_frames) {
1388                 frame->il_offsets [frame->count] = il_offset;
1389                 frame->native_offsets [frame->count] = native_offset;
1390                 frame->methods [frame->count++] = method;
1391         }
1392         return frame->count == log_config.num_frames;
1393 }
1394
1395 /*
1396  * a note about stack walks: they can cause more profiler events to fire,
1397  * so we need to make sure they don't happen after we started emitting an
1398  * event, hence the collect_bt/emit_bt split.
1399  */
1400 static void
1401 collect_bt (FrameData *data)
1402 {
1403         data->count = 0;
1404         mono_stack_walk_no_il (walk_stack, data);
1405 }
1406
1407 static void
1408 emit_bt (LogBuffer *logbuffer, FrameData *data)
1409 {
1410         emit_value (logbuffer, data->count);
1411
1412         while (data->count)
1413                 emit_method (logbuffer, data->methods [--data->count]);
1414 }
1415
1416 static void
1417 gc_alloc (MonoProfiler *prof, MonoObject *obj)
1418 {
1419         int do_bt = (!log_config.enter_leave && InterlockedRead (&log_profiler.runtime_inited) && log_config.num_frames) ? TYPE_ALLOC_BT : 0;
1420         FrameData data;
1421         uintptr_t len = mono_object_get_size (obj);
1422         /* account for object alignment in the heap */
1423         len += 7;
1424         len &= ~7;
1425
1426         if (do_bt)
1427                 collect_bt (&data);
1428
1429         ENTER_LOG (&gc_allocs_ctr, logbuffer,
1430                 EVENT_SIZE /* event */ +
1431                 LEB128_SIZE /* klass */ +
1432                 LEB128_SIZE /* obj */ +
1433                 LEB128_SIZE /* size */ +
1434                 (do_bt ? (
1435                         LEB128_SIZE /* count */ +
1436                         data.count * (
1437                                 LEB128_SIZE /* method */
1438                         )
1439                 ) : 0)
1440         );
1441
1442         emit_event (logbuffer, do_bt | TYPE_ALLOC);
1443         emit_ptr (logbuffer, mono_object_get_class (obj));
1444         emit_obj (logbuffer, obj);
1445         emit_value (logbuffer, len);
1446
1447         if (do_bt)
1448                 emit_bt (logbuffer, &data);
1449
1450         EXIT_LOG;
1451 }
1452
1453 static void
1454 gc_moves (MonoProfiler *prof, MonoObject *const *objects, uint64_t num)
1455 {
1456         ENTER_LOG (&gc_moves_ctr, logbuffer,
1457                 EVENT_SIZE /* event */ +
1458                 LEB128_SIZE /* num */ +
1459                 num * (
1460                         LEB128_SIZE /* object */
1461                 )
1462         );
1463
1464         emit_event (logbuffer, TYPE_GC_MOVE | TYPE_GC);
1465         emit_value (logbuffer, num);
1466
1467         for (int i = 0; i < num; ++i)
1468                 emit_obj (logbuffer, objects [i]);
1469
1470         EXIT_LOG;
1471 }
1472
1473 static void
1474 gc_handle (MonoProfiler *prof, int op, MonoGCHandleType type, uint32_t handle, MonoObject *obj)
1475 {
1476         int do_bt = !log_config.enter_leave && InterlockedRead (&log_profiler.runtime_inited) && log_config.num_frames;
1477         FrameData data;
1478
1479         if (do_bt)
1480                 collect_bt (&data);
1481
1482         gint32 *ctr = op == MONO_PROFILER_GC_HANDLE_CREATED ? &gc_handle_creations_ctr : &gc_handle_deletions_ctr;
1483
1484         ENTER_LOG (ctr, logbuffer,
1485                 EVENT_SIZE /* event */ +
1486                 LEB128_SIZE /* type */ +
1487                 LEB128_SIZE /* handle */ +
1488                 (op == MONO_PROFILER_GC_HANDLE_CREATED ? (
1489                         LEB128_SIZE /* obj */
1490                 ) : 0) +
1491                 (do_bt ? (
1492                         LEB128_SIZE /* count */ +
1493                         data.count * (
1494                                 LEB128_SIZE /* method */
1495                         )
1496                 ) : 0)
1497         );
1498
1499         if (op == MONO_PROFILER_GC_HANDLE_CREATED)
1500                 emit_event (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
1501         else if (op == MONO_PROFILER_GC_HANDLE_DESTROYED)
1502                 emit_event (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
1503         else
1504                 g_assert_not_reached ();
1505
1506         emit_value (logbuffer, type);
1507         emit_value (logbuffer, handle);
1508
1509         if (op == MONO_PROFILER_GC_HANDLE_CREATED)
1510                 emit_obj (logbuffer, obj);
1511
1512         if (do_bt)
1513                 emit_bt (logbuffer, &data);
1514
1515         EXIT_LOG;
1516 }
1517
1518 static void
1519 gc_handle_created (MonoProfiler *prof, uint32_t handle, MonoGCHandleType type, MonoObject *obj)
1520 {
1521         gc_handle (prof, MONO_PROFILER_GC_HANDLE_CREATED, type, handle, obj);
1522 }
1523
1524 static void
1525 gc_handle_deleted (MonoProfiler *prof, uint32_t handle, MonoGCHandleType type)
1526 {
1527         gc_handle (prof, MONO_PROFILER_GC_HANDLE_DESTROYED, type, handle, NULL);
1528 }
1529
1530 static void
1531 finalize_begin (MonoProfiler *prof)
1532 {
1533         ENTER_LOG (&finalize_begins_ctr, buf,
1534                 EVENT_SIZE /* event */
1535         );
1536
1537         emit_event (buf, TYPE_GC_FINALIZE_START | TYPE_GC);
1538
1539         EXIT_LOG;
1540 }
1541
1542 static void
1543 finalize_end (MonoProfiler *prof)
1544 {
1545         trigger_on_demand_heapshot ();
1546         if (ENABLED (PROFLOG_FINALIZATION_EVENTS)) {
1547                 ENTER_LOG (&finalize_ends_ctr, buf,
1548                         EVENT_SIZE /* event */
1549                 );
1550
1551                 emit_event (buf, TYPE_GC_FINALIZE_END | TYPE_GC);
1552
1553                 EXIT_LOG;
1554         }
1555 }
1556
1557 static void
1558 finalize_object_begin (MonoProfiler *prof, MonoObject *obj)
1559 {
1560         ENTER_LOG (&finalize_object_begins_ctr, buf,
1561                 EVENT_SIZE /* event */ +
1562                 LEB128_SIZE /* obj */
1563         );
1564
1565         emit_event (buf, TYPE_GC_FINALIZE_OBJECT_START | TYPE_GC);
1566         emit_obj (buf, obj);
1567
1568         EXIT_LOG;
1569 }
1570
1571 static void
1572 finalize_object_end (MonoProfiler *prof, MonoObject *obj)
1573 {
1574         ENTER_LOG (&finalize_object_ends_ctr, buf,
1575                 EVENT_SIZE /* event */ +
1576                 LEB128_SIZE /* obj */
1577         );
1578
1579         emit_event (buf, TYPE_GC_FINALIZE_OBJECT_END | TYPE_GC);
1580         emit_obj (buf, obj);
1581
1582         EXIT_LOG;
1583 }
1584
1585 static char*
1586 push_nesting (char *p, MonoClass *klass)
1587 {
1588         MonoClass *nesting;
1589         const char *name;
1590         const char *nspace;
1591         nesting = mono_class_get_nesting_type (klass);
1592         if (nesting) {
1593                 p = push_nesting (p, nesting);
1594                 *p++ = '/';
1595                 *p = 0;
1596         }
1597         name = mono_class_get_name (klass);
1598         nspace = mono_class_get_namespace (klass);
1599         if (*nspace) {
1600                 strcpy (p, nspace);
1601                 p += strlen (nspace);
1602                 *p++ = '.';
1603                 *p = 0;
1604         }
1605         strcpy (p, name);
1606         p += strlen (name);
1607         return p;
1608 }
1609
1610 static char*
1611 type_name (MonoClass *klass)
1612 {
1613         char buf [1024];
1614         char *p;
1615         push_nesting (buf, klass);
1616         p = (char *) g_malloc (strlen (buf) + 1);
1617         strcpy (p, buf);
1618         return p;
1619 }
1620
1621 static void
1622 image_loaded (MonoProfiler *prof, MonoImage *image)
1623 {
1624         const char *name = mono_image_get_filename (image);
1625         int nlen = strlen (name) + 1;
1626
1627         ENTER_LOG (&image_loads_ctr, logbuffer,
1628                 EVENT_SIZE /* event */ +
1629                 BYTE_SIZE /* type */ +
1630                 LEB128_SIZE /* image */ +
1631                 nlen /* name */
1632         );
1633
1634         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
1635         emit_byte (logbuffer, TYPE_IMAGE);
1636         emit_ptr (logbuffer, image);
1637         memcpy (logbuffer->cursor, name, nlen);
1638         logbuffer->cursor += nlen;
1639
1640         EXIT_LOG;
1641 }
1642
1643 static void
1644 image_unloaded (MonoProfiler *prof, MonoImage *image)
1645 {
1646         const char *name = mono_image_get_filename (image);
1647         int nlen = strlen (name) + 1;
1648
1649         ENTER_LOG (&image_unloads_ctr, logbuffer,
1650                 EVENT_SIZE /* event */ +
1651                 BYTE_SIZE /* type */ +
1652                 LEB128_SIZE /* image */ +
1653                 nlen /* name */
1654         );
1655
1656         emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
1657         emit_byte (logbuffer, TYPE_IMAGE);
1658         emit_ptr (logbuffer, image);
1659         memcpy (logbuffer->cursor, name, nlen);
1660         logbuffer->cursor += nlen;
1661
1662         EXIT_LOG;
1663 }
1664
1665 static void
1666 assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly)
1667 {
1668         char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
1669         int nlen = strlen (name) + 1;
1670         MonoImage *image = mono_assembly_get_image (assembly);
1671
1672         ENTER_LOG (&assembly_loads_ctr, logbuffer,
1673                 EVENT_SIZE /* event */ +
1674                 BYTE_SIZE /* type */ +
1675                 LEB128_SIZE /* assembly */ +
1676                 LEB128_SIZE /* image */ +
1677                 nlen /* name */
1678         );
1679
1680         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
1681         emit_byte (logbuffer, TYPE_ASSEMBLY);
1682         emit_ptr (logbuffer, assembly);
1683         emit_ptr (logbuffer, image);
1684         memcpy (logbuffer->cursor, name, nlen);
1685         logbuffer->cursor += nlen;
1686
1687         EXIT_LOG;
1688
1689         mono_free (name);
1690 }
1691
1692 static void
1693 assembly_unloaded (MonoProfiler *prof, MonoAssembly *assembly)
1694 {
1695         char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
1696         int nlen = strlen (name) + 1;
1697         MonoImage *image = mono_assembly_get_image (assembly);
1698
1699         ENTER_LOG (&assembly_unloads_ctr, logbuffer,
1700                 EVENT_SIZE /* event */ +
1701                 BYTE_SIZE /* type */ +
1702                 LEB128_SIZE /* assembly */ +
1703                 LEB128_SIZE /* image */ +
1704                 nlen /* name */
1705         );
1706
1707         emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
1708         emit_byte (logbuffer, TYPE_ASSEMBLY);
1709         emit_ptr (logbuffer, assembly);
1710         emit_ptr (logbuffer, image);
1711         memcpy (logbuffer->cursor, name, nlen);
1712         logbuffer->cursor += nlen;
1713
1714         EXIT_LOG;
1715
1716         mono_free (name);
1717 }
1718
1719 static void
1720 class_loaded (MonoProfiler *prof, MonoClass *klass)
1721 {
1722         char *name;
1723
1724         if (InterlockedRead (&log_profiler.runtime_inited))
1725                 name = mono_type_get_name (mono_class_get_type (klass));
1726         else
1727                 name = type_name (klass);
1728
1729         int nlen = strlen (name) + 1;
1730         MonoImage *image = mono_class_get_image (klass);
1731
1732         ENTER_LOG (&class_loads_ctr, logbuffer,
1733                 EVENT_SIZE /* event */ +
1734                 BYTE_SIZE /* type */ +
1735                 LEB128_SIZE /* klass */ +
1736                 LEB128_SIZE /* image */ +
1737                 nlen /* name */
1738         );
1739
1740         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
1741         emit_byte (logbuffer, TYPE_CLASS);
1742         emit_ptr (logbuffer, klass);
1743         emit_ptr (logbuffer, image);
1744         memcpy (logbuffer->cursor, name, nlen);
1745         logbuffer->cursor += nlen;
1746
1747         EXIT_LOG;
1748
1749         if (InterlockedRead (&log_profiler.runtime_inited))
1750                 mono_free (name);
1751         else
1752                 g_free (name);
1753 }
1754
1755 static void
1756 method_enter (MonoProfiler *prof, MonoMethod *method)
1757 {
1758         if (get_thread ()->call_depth++ <= log_config.max_call_depth) {
1759                 ENTER_LOG (&method_entries_ctr, logbuffer,
1760                         EVENT_SIZE /* event */ +
1761                         LEB128_SIZE /* method */
1762                 );
1763
1764                 emit_event (logbuffer, TYPE_ENTER | TYPE_METHOD);
1765                 emit_method (logbuffer, method);
1766
1767                 EXIT_LOG;
1768         }
1769 }
1770
1771 static void
1772 method_leave (MonoProfiler *prof, MonoMethod *method)
1773 {
1774         if (--get_thread ()->call_depth <= log_config.max_call_depth) {
1775                 ENTER_LOG (&method_exits_ctr, logbuffer,
1776                         EVENT_SIZE /* event */ +
1777                         LEB128_SIZE /* method */
1778                 );
1779
1780                 emit_event (logbuffer, TYPE_LEAVE | TYPE_METHOD);
1781                 emit_method (logbuffer, method);
1782
1783                 EXIT_LOG;
1784         }
1785 }
1786
1787 static void
1788 method_exc_leave (MonoProfiler *prof, MonoMethod *method, MonoObject *exc)
1789 {
1790         if (--get_thread ()->call_depth <= log_config.max_call_depth) {
1791                 ENTER_LOG (&method_exception_exits_ctr, logbuffer,
1792                         EVENT_SIZE /* event */ +
1793                         LEB128_SIZE /* method */
1794                 );
1795
1796                 emit_event (logbuffer, TYPE_EXC_LEAVE | TYPE_METHOD);
1797                 emit_method (logbuffer, method);
1798
1799                 EXIT_LOG;
1800         }
1801 }
1802
1803 static MonoProfilerCallInstrumentationFlags
1804 method_filter (MonoProfiler *prof, MonoMethod *method)
1805 {
1806         return MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE | MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE;
1807 }
1808
1809 static void
1810 method_jitted (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji)
1811 {
1812         buffer_lock ();
1813
1814         register_method_local (method, ji);
1815
1816         buffer_unlock ();
1817 }
1818
1819 static void
1820 code_buffer_new (MonoProfiler *prof, const mono_byte *buffer, uint64_t size, MonoProfilerCodeBufferType type, const void *data)
1821 {
1822         const char *name;
1823         int nlen;
1824
1825         if (type == MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE) {
1826                 name = (const char *) data;
1827                 nlen = strlen (name) + 1;
1828         } else {
1829                 name = NULL;
1830                 nlen = 0;
1831         }
1832
1833         ENTER_LOG (&code_buffers_ctr, logbuffer,
1834                 EVENT_SIZE /* event */ +
1835                 BYTE_SIZE /* type */ +
1836                 LEB128_SIZE /* buffer */ +
1837                 LEB128_SIZE /* size */ +
1838                 (name ? (
1839                         nlen /* name */
1840                 ) : 0)
1841         );
1842
1843         emit_event (logbuffer, TYPE_JITHELPER | TYPE_RUNTIME);
1844         emit_byte (logbuffer, type);
1845         emit_ptr (logbuffer, buffer);
1846         emit_value (logbuffer, size);
1847
1848         if (name) {
1849                 memcpy (logbuffer->cursor, name, nlen);
1850                 logbuffer->cursor += nlen;
1851         }
1852
1853         EXIT_LOG;
1854 }
1855
1856 static void
1857 throw_exc (MonoProfiler *prof, MonoObject *object)
1858 {
1859         int do_bt = (!log_config.enter_leave && InterlockedRead (&log_profiler.runtime_inited) && log_config.num_frames) ? TYPE_THROW_BT : 0;
1860         FrameData data;
1861
1862         if (do_bt)
1863                 collect_bt (&data);
1864
1865         ENTER_LOG (&exception_throws_ctr, logbuffer,
1866                 EVENT_SIZE /* event */ +
1867                 LEB128_SIZE /* object */ +
1868                 (do_bt ? (
1869                         LEB128_SIZE /* count */ +
1870                         data.count * (
1871                                 LEB128_SIZE /* method */
1872                         )
1873                 ) : 0)
1874         );
1875
1876         emit_event (logbuffer, do_bt | TYPE_EXCEPTION);
1877         emit_obj (logbuffer, object);
1878
1879         if (do_bt)
1880                 emit_bt (logbuffer, &data);
1881
1882         EXIT_LOG;
1883 }
1884
1885 static void
1886 clause_exc (MonoProfiler *prof, MonoMethod *method, uint32_t clause_num, MonoExceptionEnum clause_type, MonoObject *exc)
1887 {
1888         ENTER_LOG (&exception_clauses_ctr, logbuffer,
1889                 EVENT_SIZE /* event */ +
1890                 BYTE_SIZE /* clause type */ +
1891                 LEB128_SIZE /* clause num */ +
1892                 LEB128_SIZE /* method */
1893         );
1894
1895         emit_event (logbuffer, TYPE_EXCEPTION | TYPE_CLAUSE);
1896         emit_byte (logbuffer, clause_type);
1897         emit_value (logbuffer, clause_num);
1898         emit_method (logbuffer, method);
1899         emit_obj (logbuffer, exc);
1900
1901         EXIT_LOG;
1902 }
1903
1904 static void
1905 monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEvent ev)
1906 {
1907         int do_bt = (!log_config.enter_leave && InterlockedRead (&log_profiler.runtime_inited) && log_config.num_frames) ? TYPE_MONITOR_BT : 0;
1908         FrameData data;
1909
1910         if (do_bt)
1911                 collect_bt (&data);
1912
1913         ENTER_LOG (&monitor_events_ctr, logbuffer,
1914                 EVENT_SIZE /* event */ +
1915                 BYTE_SIZE /* ev */ +
1916                 LEB128_SIZE /* object */ +
1917                 (do_bt ? (
1918                         LEB128_SIZE /* count */ +
1919                         data.count * (
1920                                 LEB128_SIZE /* method */
1921                         )
1922                 ) : 0)
1923         );
1924
1925         emit_event (logbuffer, do_bt | TYPE_MONITOR);
1926         emit_byte (logbuffer, ev);
1927         emit_obj (logbuffer, object);
1928
1929         if (do_bt)
1930                 emit_bt (logbuffer, &data);
1931
1932         EXIT_LOG;
1933 }
1934
1935 static void
1936 monitor_contention (MonoProfiler *prof, MonoObject *object)
1937 {
1938         monitor_event (prof, object, MONO_PROFILER_MONITOR_CONTENTION);
1939 }
1940
1941 static void
1942 monitor_acquired (MonoProfiler *prof, MonoObject *object)
1943 {
1944         monitor_event (prof, object, MONO_PROFILER_MONITOR_DONE);
1945 }
1946
1947 static void
1948 monitor_failed (MonoProfiler *prof, MonoObject *object)
1949 {
1950         monitor_event (prof, object, MONO_PROFILER_MONITOR_FAIL);
1951 }
1952
1953 static void
1954 thread_start (MonoProfiler *prof, uintptr_t tid)
1955 {
1956         ENTER_LOG (&thread_starts_ctr, logbuffer,
1957                 EVENT_SIZE /* event */ +
1958                 BYTE_SIZE /* type */ +
1959                 LEB128_SIZE /* tid */
1960         );
1961
1962         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
1963         emit_byte (logbuffer, TYPE_THREAD);
1964         emit_ptr (logbuffer, (void*) tid);
1965
1966         EXIT_LOG;
1967 }
1968
1969 static void
1970 thread_end (MonoProfiler *prof, uintptr_t tid)
1971 {
1972         ENTER_LOG (&thread_ends_ctr, logbuffer,
1973                 EVENT_SIZE /* event */ +
1974                 BYTE_SIZE /* type */ +
1975                 LEB128_SIZE /* tid */
1976         );
1977
1978         emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
1979         emit_byte (logbuffer, TYPE_THREAD);
1980         emit_ptr (logbuffer, (void*) tid);
1981
1982         EXIT_LOG_EXPLICIT (NO_SEND);
1983
1984         MonoProfilerThread *thread = get_thread ();
1985
1986         thread->ended = TRUE;
1987         remove_thread (thread);
1988
1989         PROF_TLS_SET (NULL);
1990 }
1991
1992 static void
1993 thread_name (MonoProfiler *prof, uintptr_t tid, const char *name)
1994 {
1995         int len = strlen (name) + 1;
1996
1997         ENTER_LOG (&thread_names_ctr, logbuffer,
1998                 EVENT_SIZE /* event */ +
1999                 BYTE_SIZE /* type */ +
2000                 LEB128_SIZE /* tid */ +
2001                 len /* name */
2002         );
2003
2004         emit_event (logbuffer, TYPE_METADATA);
2005         emit_byte (logbuffer, TYPE_THREAD);
2006         emit_ptr (logbuffer, (void*)tid);
2007         memcpy (logbuffer->cursor, name, len);
2008         logbuffer->cursor += len;
2009
2010         EXIT_LOG;
2011 }
2012
2013 static void
2014 domain_loaded (MonoProfiler *prof, MonoDomain *domain)
2015 {
2016         ENTER_LOG (&domain_loads_ctr, logbuffer,
2017                 EVENT_SIZE /* event */ +
2018                 BYTE_SIZE /* type */ +
2019                 LEB128_SIZE /* domain id */
2020         );
2021
2022         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
2023         emit_byte (logbuffer, TYPE_DOMAIN);
2024         emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
2025
2026         EXIT_LOG;
2027 }
2028
2029 static void
2030 domain_unloaded (MonoProfiler *prof, MonoDomain *domain)
2031 {
2032         ENTER_LOG (&domain_unloads_ctr, logbuffer,
2033                 EVENT_SIZE /* event */ +
2034                 BYTE_SIZE /* type */ +
2035                 LEB128_SIZE /* domain id */
2036         );
2037
2038         emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
2039         emit_byte (logbuffer, TYPE_DOMAIN);
2040         emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
2041
2042         EXIT_LOG;
2043 }
2044
2045 static void
2046 domain_name (MonoProfiler *prof, MonoDomain *domain, const char *name)
2047 {
2048         int nlen = strlen (name) + 1;
2049
2050         ENTER_LOG (&domain_names_ctr, logbuffer,
2051                 EVENT_SIZE /* event */ +
2052                 BYTE_SIZE /* type */ +
2053                 LEB128_SIZE /* domain id */ +
2054                 nlen /* name */
2055         );
2056
2057         emit_event (logbuffer, TYPE_METADATA);
2058         emit_byte (logbuffer, TYPE_DOMAIN);
2059         emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
2060         memcpy (logbuffer->cursor, name, nlen);
2061         logbuffer->cursor += nlen;
2062
2063         EXIT_LOG;
2064 }
2065
2066 static void
2067 context_loaded (MonoProfiler *prof, MonoAppContext *context)
2068 {
2069         ENTER_LOG (&context_loads_ctr, logbuffer,
2070                 EVENT_SIZE /* event */ +
2071                 BYTE_SIZE /* type */ +
2072                 LEB128_SIZE /* context id */ +
2073                 LEB128_SIZE /* domain id */
2074         );
2075
2076         emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
2077         emit_byte (logbuffer, TYPE_CONTEXT);
2078         emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_id (context));
2079         emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_domain_id (context));
2080
2081         EXIT_LOG;
2082 }
2083
2084 static void
2085 context_unloaded (MonoProfiler *prof, MonoAppContext *context)
2086 {
2087         ENTER_LOG (&context_unloads_ctr, logbuffer,
2088                 EVENT_SIZE /* event */ +
2089                 BYTE_SIZE /* type */ +
2090                 LEB128_SIZE /* context id */ +
2091                 LEB128_SIZE /* domain id */
2092         );
2093
2094         emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
2095         emit_byte (logbuffer, TYPE_CONTEXT);
2096         emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_id (context));
2097         emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_domain_id (context));
2098
2099         EXIT_LOG;
2100 }
2101
2102 typedef struct {
2103         MonoMethod *method;
2104         MonoDomain *domain;
2105         void *base_address;
2106         int offset;
2107 } AsyncFrameInfo;
2108
2109 typedef struct {
2110         MonoLockFreeQueueNode node;
2111         uint64_t time;
2112         uintptr_t tid;
2113         const void *ip;
2114         int count;
2115         AsyncFrameInfo frames [MONO_ZERO_LEN_ARRAY];
2116 } SampleHit;
2117
2118 static mono_bool
2119 async_walk_stack (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void *data)
2120 {
2121         SampleHit *sample = (SampleHit *) data;
2122
2123         if (sample->count < log_config.num_frames) {
2124                 int i = sample->count;
2125
2126                 sample->frames [i].method = method;
2127                 sample->frames [i].domain = domain;
2128                 sample->frames [i].base_address = base_address;
2129                 sample->frames [i].offset = offset;
2130
2131                 sample->count++;
2132         }
2133
2134         return sample->count == log_config.num_frames;
2135 }
2136
2137 #define SAMPLE_SLOT_SIZE(FRAMES) (sizeof (SampleHit) + sizeof (AsyncFrameInfo) * (FRAMES - MONO_ZERO_LEN_ARRAY))
2138 #define SAMPLE_BLOCK_SIZE (mono_pagesize ())
2139
2140 static void
2141 enqueue_sample_hit (gpointer p)
2142 {
2143         SampleHit *sample = p;
2144
2145         mono_lock_free_queue_node_unpoison (&sample->node);
2146         mono_lock_free_queue_enqueue (&log_profiler.dumper_queue, &sample->node);
2147         mono_os_sem_post (&log_profiler.dumper_queue_sem);
2148 }
2149
2150 static void
2151 mono_sample_hit (MonoProfiler *profiler, const mono_byte *ip, const void *context)
2152 {
2153         /*
2154          * Please note: We rely on the runtime loading the profiler with
2155          * MONO_DL_EAGER (RTLD_NOW) so that references to runtime functions within
2156          * this function (and its siblings) are resolved when the profiler is
2157          * loaded. Otherwise, we would potentially invoke the dynamic linker when
2158          * invoking runtime functions, which is not async-signal-safe.
2159          */
2160
2161         if (InterlockedRead (&log_profiler.in_shutdown))
2162                 return;
2163
2164         SampleHit *sample = (SampleHit *) mono_lock_free_queue_dequeue (&profiler->sample_reuse_queue);
2165
2166         if (!sample) {
2167                 /*
2168                  * If we're out of reusable sample events and we're not allowed to
2169                  * allocate more, we have no choice but to drop the event.
2170                  */
2171                 if (InterlockedRead (&sample_allocations_ctr) >= log_config.max_allocated_sample_hits)
2172                         return;
2173
2174                 sample = mono_lock_free_alloc (&profiler->sample_allocator);
2175                 mono_lock_free_queue_node_init (&sample->node, TRUE);
2176
2177                 InterlockedIncrement (&sample_allocations_ctr);
2178         }
2179
2180         sample->count = 0;
2181         mono_stack_walk_async_safe (&async_walk_stack, (void *) context, sample);
2182
2183         sample->time = current_time ();
2184         sample->tid = thread_id ();
2185         sample->ip = ip;
2186
2187         mono_thread_hazardous_try_free (sample, enqueue_sample_hit);
2188 }
2189
2190 static uintptr_t *code_pages = 0;
2191 static int num_code_pages = 0;
2192 static int size_code_pages = 0;
2193 #define CPAGE_SHIFT (9)
2194 #define CPAGE_SIZE (1 << CPAGE_SHIFT)
2195 #define CPAGE_MASK (~(CPAGE_SIZE - 1))
2196 #define CPAGE_ADDR(p) ((p) & CPAGE_MASK)
2197
2198 static uintptr_t
2199 add_code_page (uintptr_t *hash, uintptr_t hsize, uintptr_t page)
2200 {
2201         uintptr_t i;
2202         uintptr_t start_pos;
2203         start_pos = (page >> CPAGE_SHIFT) % hsize;
2204         i = start_pos;
2205         do {
2206                 if (hash [i] && CPAGE_ADDR (hash [i]) == CPAGE_ADDR (page)) {
2207                         return 0;
2208                 } else if (!hash [i]) {
2209                         hash [i] = page;
2210                         return 1;
2211                 }
2212                 /* wrap around */
2213                 if (++i == hsize)
2214                         i = 0;
2215         } while (i != start_pos);
2216         g_assert_not_reached ();
2217         return 0;
2218 }
2219
2220 static void
2221 add_code_pointer (uintptr_t ip)
2222 {
2223         uintptr_t i;
2224         if (num_code_pages * 2 >= size_code_pages) {
2225                 uintptr_t *n;
2226                 uintptr_t old_size = size_code_pages;
2227                 size_code_pages *= 2;
2228                 if (size_code_pages == 0)
2229                         size_code_pages = 16;
2230                 n = (uintptr_t *) g_calloc (sizeof (uintptr_t) * size_code_pages, 1);
2231                 for (i = 0; i < old_size; ++i) {
2232                         if (code_pages [i])
2233                                 add_code_page (n, size_code_pages, code_pages [i]);
2234                 }
2235                 if (code_pages)
2236                         g_free (code_pages);
2237                 code_pages = n;
2238         }
2239         num_code_pages += add_code_page (code_pages, size_code_pages, ip & CPAGE_MASK);
2240 }
2241
2242 /* ELF code crashes on some systems. */
2243 //#if defined(HAVE_DL_ITERATE_PHDR) && defined(ELFMAG0)
2244 #if 0
2245 static void
2246 dump_ubin (const char *filename, uintptr_t load_addr, uint64_t offset, uintptr_t size)
2247 {
2248         int len = strlen (filename) + 1;
2249
2250         ENTER_LOG (&sample_ubins_ctr, logbuffer,
2251                 EVENT_SIZE /* event */ +
2252                 LEB128_SIZE /* load address */ +
2253                 LEB128_SIZE /* offset */ +
2254                 LEB128_SIZE /* size */ +
2255                 nlen /* file name */
2256         );
2257
2258         emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_UBIN);
2259         emit_ptr (logbuffer, load_addr);
2260         emit_uvalue (logbuffer, offset);
2261         emit_uvalue (logbuffer, size);
2262         memcpy (logbuffer->cursor, filename, len);
2263         logbuffer->cursor += len;
2264
2265         EXIT_LOG;
2266 }
2267 #endif
2268
2269 static void
2270 dump_usym (const char *name, uintptr_t value, uintptr_t size)
2271 {
2272         int len = strlen (name) + 1;
2273
2274         ENTER_LOG (&sample_usyms_ctr, logbuffer,
2275                 EVENT_SIZE /* event */ +
2276                 LEB128_SIZE /* value */ +
2277                 LEB128_SIZE /* size */ +
2278                 len /* name */
2279         );
2280
2281         emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_USYM);
2282         emit_ptr (logbuffer, (void*)value);
2283         emit_value (logbuffer, size);
2284         memcpy (logbuffer->cursor, name, len);
2285         logbuffer->cursor += len;
2286
2287         EXIT_LOG;
2288 }
2289
2290 /* ELF code crashes on some systems. */
2291 //#if defined(ELFMAG0)
2292 #if 0
2293
2294 #if SIZEOF_VOID_P == 4
2295 #define ELF_WSIZE 32
2296 #else
2297 #define ELF_WSIZE 64
2298 #endif
2299 #ifndef ElfW
2300 #define ElfW(type)      _ElfW (Elf, ELF_WSIZE, type)
2301 #define _ElfW(e,w,t)    _ElfW_1 (e, w, _##t)
2302 #define _ElfW_1(e,w,t)  e##w##t
2303 #endif
2304
2305 static void
2306 dump_elf_symbols (ElfW(Sym) *symbols, int num_symbols, const char *strtab, void *load_addr)
2307 {
2308         int i;
2309         for (i = 0; i < num_symbols; ++i) {
2310                 const char* sym;
2311                 sym =  strtab + symbols [i].st_name;
2312                 if (!symbols [i].st_name || !symbols [i].st_size || (symbols [i].st_info & 0xf) != STT_FUNC)
2313                         continue;
2314                 dump_usym (sym, (uintptr_t)load_addr + symbols [i].st_value, symbols [i].st_size);
2315         }
2316 }
2317
2318 static int
2319 read_elf_symbols (MonoProfiler *prof, const char *filename, void *load_addr)
2320 {
2321         int fd, i;
2322         void *data;
2323         struct stat statb;
2324         uint64_t file_size;
2325         ElfW(Ehdr) *header;
2326         ElfW(Shdr) *sheader;
2327         ElfW(Shdr) *shstrtabh;
2328         ElfW(Shdr) *symtabh = NULL;
2329         ElfW(Shdr) *strtabh = NULL;
2330         ElfW(Sym) *symbols = NULL;
2331         const char *strtab;
2332         int num_symbols;
2333
2334         fd = open (filename, O_RDONLY);
2335         if (fd < 0)
2336                 return 0;
2337         if (fstat (fd, &statb) != 0) {
2338                 close (fd);
2339                 return 0;
2340         }
2341         file_size = statb.st_size;
2342         data = mmap (NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
2343         close (fd);
2344         if (data == MAP_FAILED)
2345                 return 0;
2346         header = data;
2347         if (header->e_ident [EI_MAG0] != ELFMAG0 ||
2348                         header->e_ident [EI_MAG1] != ELFMAG1 ||
2349                         header->e_ident [EI_MAG2] != ELFMAG2 ||
2350                         header->e_ident [EI_MAG3] != ELFMAG3 ) {
2351                 munmap (data, file_size);
2352                 return 0;
2353         }
2354         sheader = (void*)((char*)data + header->e_shoff);
2355         shstrtabh = (void*)((char*)sheader + (header->e_shentsize * header->e_shstrndx));
2356         strtab = (const char*)data + shstrtabh->sh_offset;
2357         for (i = 0; i < header->e_shnum; ++i) {
2358                 if (sheader->sh_type == SHT_SYMTAB) {
2359                         symtabh = sheader;
2360                         strtabh = (void*)((char*)data + header->e_shoff + sheader->sh_link * header->e_shentsize);
2361                         break;
2362                 }
2363                 sheader = (void*)((char*)sheader + header->e_shentsize);
2364         }
2365         if (!symtabh || !strtabh) {
2366                 munmap (data, file_size);
2367                 return 0;
2368         }
2369         strtab = (const char*)data + strtabh->sh_offset;
2370         num_symbols = symtabh->sh_size / symtabh->sh_entsize;
2371         symbols = (void*)((char*)data + symtabh->sh_offset);
2372         dump_elf_symbols (symbols, num_symbols, strtab, load_addr);
2373         munmap (data, file_size);
2374         return 1;
2375 }
2376 #endif
2377
2378 /* ELF code crashes on some systems. */
2379 //#if defined(HAVE_DL_ITERATE_PHDR) && defined(ELFMAG0)
2380 #if 0
2381 static int
2382 elf_dl_callback (struct dl_phdr_info *info, size_t size, void *data)
2383 {
2384         char buf [256];
2385         const char *filename;
2386         BinaryObject *obj;
2387         char *a = (void*)info->dlpi_addr;
2388         int i, num_sym;
2389         ElfW(Dyn) *dyn = NULL;
2390         ElfW(Sym) *symtab = NULL;
2391         ElfW(Word) *hash_table = NULL;
2392         ElfW(Ehdr) *header = NULL;
2393         const char* strtab = NULL;
2394         for (obj = log_profiler.binary_objects; obj; obj = obj->next) {
2395                 if (obj->addr == a)
2396                         return 0;
2397         }
2398         filename = info->dlpi_name;
2399         if (!filename)
2400                 return 0;
2401         if (!info->dlpi_addr && !filename [0]) {
2402                 int l = readlink ("/proc/self/exe", buf, sizeof (buf) - 1);
2403                 if (l > 0) {
2404                         buf [l] = 0;
2405                         filename = buf;
2406                 }
2407         }
2408         obj = g_calloc (sizeof (BinaryObject), 1);
2409         obj->addr = (void*)info->dlpi_addr;
2410         obj->name = pstrdup (filename);
2411         obj->next = log_profiler.binary_objects;
2412         log_profiler.binary_objects = obj;
2413         a = NULL;
2414         for (i = 0; i < info->dlpi_phnum; ++i) {
2415                 if (info->dlpi_phdr[i].p_type == PT_LOAD && !header) {
2416                         header = (ElfW(Ehdr)*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
2417                         if (header->e_ident [EI_MAG0] != ELFMAG0 ||
2418                                         header->e_ident [EI_MAG1] != ELFMAG1 ||
2419                                         header->e_ident [EI_MAG2] != ELFMAG2 ||
2420                                         header->e_ident [EI_MAG3] != ELFMAG3 ) {
2421                                 header = NULL;
2422                         }
2423                         dump_ubin (filename, info->dlpi_addr + info->dlpi_phdr[i].p_vaddr, info->dlpi_phdr[i].p_offset, info->dlpi_phdr[i].p_memsz);
2424                 } else if (info->dlpi_phdr[i].p_type == PT_DYNAMIC) {
2425                         dyn = (ElfW(Dyn) *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
2426                 }
2427         }
2428         if (read_elf_symbols (filename, (void*)info->dlpi_addr))
2429                 return 0;
2430         if (!info->dlpi_name || !info->dlpi_name[0])
2431                 return 0;
2432         if (!dyn)
2433                 return 0;
2434         for (i = 0; dyn [i].d_tag != DT_NULL; ++i) {
2435                 if (dyn [i].d_tag == DT_SYMTAB) {
2436                         symtab = (ElfW(Sym) *)(a + dyn [i].d_un.d_ptr);
2437                 } else if (dyn [i].d_tag == DT_HASH) {
2438                         hash_table = (ElfW(Word) *)(a + dyn [i].d_un.d_ptr);
2439                 } else if (dyn [i].d_tag == DT_STRTAB) {
2440                         strtab = (const char*)(a + dyn [i].d_un.d_ptr);
2441                 }
2442         }
2443         if (!hash_table)
2444                 return 0;
2445         num_sym = hash_table [1];
2446         dump_elf_symbols (symtab, num_sym, strtab, (void*)info->dlpi_addr);
2447         return 0;
2448 }
2449
2450 static int
2451 load_binaries (void)
2452 {
2453         dl_iterate_phdr (elf_dl_callback, NULL);
2454         return 1;
2455 }
2456 #else
2457 static int
2458 load_binaries (void)
2459 {
2460         return 0;
2461 }
2462 #endif
2463
2464 static const char*
2465 symbol_for (uintptr_t code)
2466 {
2467 #ifdef HAVE_DLADDR
2468         void *ip = (void*)code;
2469         Dl_info di;
2470         if (dladdr (ip, &di)) {
2471                 if (di.dli_sname)
2472                         return di.dli_sname;
2473         } else {
2474         /*      char **names;
2475                 names = backtrace_symbols (&ip, 1);
2476                 if (names) {
2477                         const char* p = names [0];
2478                         g_free (names);
2479                         return p;
2480                 }
2481                 */
2482         }
2483 #endif
2484         return NULL;
2485 }
2486
2487 static void
2488 dump_unmanaged_coderefs (void)
2489 {
2490         int i;
2491         const char* last_symbol;
2492         uintptr_t addr, page_end;
2493
2494         if (load_binaries ())
2495                 return;
2496         for (i = 0; i < size_code_pages; ++i) {
2497                 const char* sym;
2498                 if (!code_pages [i] || code_pages [i] & 1)
2499                         continue;
2500                 last_symbol = NULL;
2501                 addr = CPAGE_ADDR (code_pages [i]);
2502                 page_end = addr + CPAGE_SIZE;
2503                 code_pages [i] |= 1;
2504                 /* we dump the symbols for the whole page */
2505                 for (; addr < page_end; addr += 16) {
2506                         sym = symbol_for (addr);
2507                         if (sym && sym == last_symbol)
2508                                 continue;
2509                         last_symbol = sym;
2510                         if (!sym)
2511                                 continue;
2512                         dump_usym (sym, addr, 0); /* let's not guess the size */
2513                 }
2514         }
2515 }
2516
2517 static void
2518 counters_add_agent (MonoCounter *counter)
2519 {
2520         if (InterlockedRead (&log_profiler.in_shutdown))
2521                 return;
2522
2523         MonoCounterAgent *agent, *item;
2524
2525         mono_os_mutex_lock (&log_profiler.counters_mutex);
2526
2527         for (agent = log_profiler.counters; agent; agent = agent->next) {
2528                 if (agent->counter == counter) {
2529                         agent->value_size = 0;
2530                         if (agent->value) {
2531                                 g_free (agent->value);
2532                                 agent->value = NULL;
2533                         }
2534                         goto done;
2535                 }
2536         }
2537
2538         agent = (MonoCounterAgent *) g_malloc (sizeof (MonoCounterAgent));
2539         agent->counter = counter;
2540         agent->value = NULL;
2541         agent->value_size = 0;
2542         agent->index = log_profiler.counters_index++;
2543         agent->emitted = FALSE;
2544         agent->next = NULL;
2545
2546         if (!log_profiler.counters) {
2547                 log_profiler.counters = agent;
2548         } else {
2549                 item = log_profiler.counters;
2550                 while (item->next)
2551                         item = item->next;
2552                 item->next = agent;
2553         }
2554
2555 done:
2556         mono_os_mutex_unlock (&log_profiler.counters_mutex);
2557 }
2558
2559 static mono_bool
2560 counters_init_foreach_callback (MonoCounter *counter, gpointer data)
2561 {
2562         counters_add_agent (counter);
2563         return TRUE;
2564 }
2565
2566 static void
2567 counters_init (void)
2568 {
2569         mono_os_mutex_init (&log_profiler.counters_mutex);
2570
2571         log_profiler.counters_index = 1;
2572
2573         mono_counters_on_register (&counters_add_agent);
2574         mono_counters_foreach (counters_init_foreach_callback, NULL);
2575 }
2576
2577 static void
2578 counters_emit (void)
2579 {
2580         MonoCounterAgent *agent;
2581         int len = 0;
2582         int size =
2583                 EVENT_SIZE /* event */ +
2584                 LEB128_SIZE /* len */
2585         ;
2586
2587         mono_os_mutex_lock (&log_profiler.counters_mutex);
2588
2589         for (agent = log_profiler.counters; agent; agent = agent->next) {
2590                 if (agent->emitted)
2591                         continue;
2592
2593                 size +=
2594                         LEB128_SIZE /* section */ +
2595                         strlen (mono_counter_get_name (agent->counter)) + 1 /* name */ +
2596                         BYTE_SIZE /* type */ +
2597                         BYTE_SIZE /* unit */ +
2598                         BYTE_SIZE /* variance */ +
2599                         LEB128_SIZE /* index */
2600                 ;
2601
2602                 len++;
2603         }
2604
2605         if (!len)
2606                 goto done;
2607
2608         ENTER_LOG (&counter_descriptors_ctr, logbuffer, size);
2609
2610         emit_event (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
2611         emit_value (logbuffer, len);
2612
2613         for (agent = log_profiler.counters; agent; agent = agent->next) {
2614                 const char *name;
2615
2616                 if (agent->emitted)
2617                         continue;
2618
2619                 name = mono_counter_get_name (agent->counter);
2620                 emit_value (logbuffer, mono_counter_get_section (agent->counter));
2621                 emit_string (logbuffer, name, strlen (name) + 1);
2622                 emit_byte (logbuffer, mono_counter_get_type (agent->counter));
2623                 emit_byte (logbuffer, mono_counter_get_unit (agent->counter));
2624                 emit_byte (logbuffer, mono_counter_get_variance (agent->counter));
2625                 emit_value (logbuffer, agent->index);
2626
2627                 agent->emitted = TRUE;
2628         }
2629
2630         EXIT_LOG;
2631
2632 done:
2633         mono_os_mutex_unlock (&log_profiler.counters_mutex);
2634 }
2635
2636 static void
2637 counters_sample (uint64_t timestamp)
2638 {
2639         MonoCounterAgent *agent;
2640         MonoCounter *counter;
2641         int type;
2642         int buffer_size;
2643         void *buffer;
2644         int size;
2645
2646         counters_emit ();
2647
2648         buffer_size = 8;
2649         buffer = g_calloc (1, buffer_size);
2650
2651         mono_os_mutex_lock (&log_profiler.counters_mutex);
2652
2653         size =
2654                 EVENT_SIZE /* event */
2655         ;
2656
2657         for (agent = log_profiler.counters; agent; agent = agent->next) {
2658                 size +=
2659                         LEB128_SIZE /* index */ +
2660                         BYTE_SIZE /* type */ +
2661                         mono_counter_get_size (agent->counter) /* value */
2662                 ;
2663         }
2664
2665         size +=
2666                 LEB128_SIZE /* stop marker */
2667         ;
2668
2669         ENTER_LOG (&counter_samples_ctr, logbuffer, size);
2670
2671         emit_event_time (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE, timestamp);
2672
2673         for (agent = log_profiler.counters; agent; agent = agent->next) {
2674                 size_t size;
2675
2676                 counter = agent->counter;
2677
2678                 size = mono_counter_get_size (counter);
2679
2680                 if (size > buffer_size) {
2681                         buffer_size = size;
2682                         buffer = g_realloc (buffer, buffer_size);
2683                 }
2684
2685                 memset (buffer, 0, buffer_size);
2686
2687                 g_assert (mono_counters_sample (counter, buffer, size));
2688
2689                 type = mono_counter_get_type (counter);
2690
2691                 if (!agent->value) {
2692                         agent->value = g_calloc (1, size);
2693                         agent->value_size = size;
2694                 } else {
2695                         if (type == MONO_COUNTER_STRING) {
2696                                 if (strcmp (agent->value, buffer) == 0)
2697                                         continue;
2698                         } else {
2699                                 if (agent->value_size == size && memcmp (agent->value, buffer, size) == 0)
2700                                         continue;
2701                         }
2702                 }
2703
2704                 emit_uvalue (logbuffer, agent->index);
2705                 emit_byte (logbuffer, type);
2706                 switch (type) {
2707                 case MONO_COUNTER_INT:
2708 #if SIZEOF_VOID_P == 4
2709                 case MONO_COUNTER_WORD:
2710 #endif
2711                         emit_svalue (logbuffer, *(int*)buffer - *(int*)agent->value);
2712                         break;
2713                 case MONO_COUNTER_UINT:
2714                         emit_uvalue (logbuffer, *(guint*)buffer - *(guint*)agent->value);
2715                         break;
2716                 case MONO_COUNTER_TIME_INTERVAL:
2717                 case MONO_COUNTER_LONG:
2718 #if SIZEOF_VOID_P == 8
2719                 case MONO_COUNTER_WORD:
2720 #endif
2721                         emit_svalue (logbuffer, *(gint64*)buffer - *(gint64*)agent->value);
2722                         break;
2723                 case MONO_COUNTER_ULONG:
2724                         emit_uvalue (logbuffer, *(guint64*)buffer - *(guint64*)agent->value);
2725                         break;
2726                 case MONO_COUNTER_DOUBLE:
2727                         emit_double (logbuffer, *(double*)buffer);
2728                         break;
2729                 case MONO_COUNTER_STRING:
2730                         if (size == 0) {
2731                                 emit_byte (logbuffer, 0);
2732                         } else {
2733                                 emit_byte (logbuffer, 1);
2734                                 emit_string (logbuffer, (char*)buffer, size);
2735                         }
2736                         break;
2737                 default:
2738                         g_assert_not_reached ();
2739                 }
2740
2741                 if (type == MONO_COUNTER_STRING && size > agent->value_size) {
2742                         agent->value = g_realloc (agent->value, size);
2743                         agent->value_size = size;
2744                 }
2745
2746                 if (size > 0)
2747                         memcpy (agent->value, buffer, size);
2748         }
2749         g_free (buffer);
2750
2751         emit_value (logbuffer, 0);
2752
2753         EXIT_LOG;
2754
2755         mono_os_mutex_unlock (&log_profiler.counters_mutex);
2756 }
2757
2758 static void
2759 perfcounters_emit (void)
2760 {
2761         PerfCounterAgent *pcagent;
2762         int len = 0;
2763         int size =
2764                 EVENT_SIZE /* event */ +
2765                 LEB128_SIZE /* len */
2766         ;
2767
2768         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next) {
2769                 if (pcagent->emitted)
2770                         continue;
2771
2772                 size +=
2773                         LEB128_SIZE /* section */ +
2774                         strlen (pcagent->category_name) + 1 /* category name */ +
2775                         strlen (pcagent->name) + 1 /* name */ +
2776                         BYTE_SIZE /* type */ +
2777                         BYTE_SIZE /* unit */ +
2778                         BYTE_SIZE /* variance */ +
2779                         LEB128_SIZE /* index */
2780                 ;
2781
2782                 len++;
2783         }
2784
2785         if (!len)
2786                 return;
2787
2788         ENTER_LOG (&perfcounter_descriptors_ctr, logbuffer, size);
2789
2790         emit_event (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
2791         emit_value (logbuffer, len);
2792
2793         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next) {
2794                 if (pcagent->emitted)
2795                         continue;
2796
2797                 emit_value (logbuffer, MONO_COUNTER_PERFCOUNTERS);
2798                 emit_string (logbuffer, pcagent->category_name, strlen (pcagent->category_name) + 1);
2799                 emit_string (logbuffer, pcagent->name, strlen (pcagent->name) + 1);
2800                 emit_byte (logbuffer, MONO_COUNTER_LONG);
2801                 emit_byte (logbuffer, MONO_COUNTER_RAW);
2802                 emit_byte (logbuffer, MONO_COUNTER_VARIABLE);
2803                 emit_value (logbuffer, pcagent->index);
2804
2805                 pcagent->emitted = TRUE;
2806         }
2807
2808         EXIT_LOG;
2809 }
2810
2811 static gboolean
2812 perfcounters_foreach (char *category_name, char *name, unsigned char type, gint64 value, gpointer user_data)
2813 {
2814         PerfCounterAgent *pcagent;
2815
2816         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next) {
2817                 if (strcmp (pcagent->category_name, category_name) != 0 || strcmp (pcagent->name, name) != 0)
2818                         continue;
2819                 if (pcagent->value == value)
2820                         return TRUE;
2821
2822                 pcagent->value = value;
2823                 pcagent->updated = TRUE;
2824                 pcagent->deleted = FALSE;
2825                 return TRUE;
2826         }
2827
2828         pcagent = g_new0 (PerfCounterAgent, 1);
2829         pcagent->next = log_profiler.perfcounters;
2830         pcagent->index = log_profiler.counters_index++;
2831         pcagent->category_name = g_strdup (category_name);
2832         pcagent->name = g_strdup (name);
2833         pcagent->value = value;
2834         pcagent->emitted = FALSE;
2835         pcagent->updated = TRUE;
2836         pcagent->deleted = FALSE;
2837
2838         log_profiler.perfcounters = pcagent;
2839
2840         return TRUE;
2841 }
2842
2843 static void
2844 perfcounters_sample (uint64_t timestamp)
2845 {
2846         PerfCounterAgent *pcagent;
2847         int len = 0;
2848         int size;
2849
2850         mono_os_mutex_lock (&log_profiler.counters_mutex);
2851
2852         /* mark all perfcounters as deleted, foreach will unmark them as necessary */
2853         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next)
2854                 pcagent->deleted = TRUE;
2855
2856         mono_perfcounter_foreach (perfcounters_foreach, NULL);
2857
2858         perfcounters_emit ();
2859
2860         size =
2861                 EVENT_SIZE /* event */
2862         ;
2863
2864         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next) {
2865                 if (pcagent->deleted || !pcagent->updated)
2866                         continue;
2867
2868                 size +=
2869                         LEB128_SIZE /* index */ +
2870                         BYTE_SIZE /* type */ +
2871                         LEB128_SIZE /* value */
2872                 ;
2873
2874                 len++;
2875         }
2876
2877         if (!len)
2878                 goto done;
2879
2880         size +=
2881                 LEB128_SIZE /* stop marker */
2882         ;
2883
2884         ENTER_LOG (&perfcounter_samples_ctr, logbuffer, size);
2885
2886         emit_event_time (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE, timestamp);
2887
2888         for (pcagent = log_profiler.perfcounters; pcagent; pcagent = pcagent->next) {
2889                 if (pcagent->deleted || !pcagent->updated)
2890                         continue;
2891                 emit_uvalue (logbuffer, pcagent->index);
2892                 emit_byte (logbuffer, MONO_COUNTER_LONG);
2893                 emit_svalue (logbuffer, pcagent->value);
2894
2895                 pcagent->updated = FALSE;
2896         }
2897
2898         emit_value (logbuffer, 0);
2899
2900         EXIT_LOG;
2901
2902 done:
2903         mono_os_mutex_unlock (&log_profiler.counters_mutex);
2904 }
2905
2906 static void
2907 counters_and_perfcounters_sample (void)
2908 {
2909         uint64_t now = current_time ();
2910
2911         counters_sample (now);
2912         perfcounters_sample (now);
2913 }
2914
2915 typedef struct {
2916         MonoLockFreeQueueNode node;
2917         MonoMethod *method;
2918 } MethodNode;
2919
2920 typedef struct {
2921         int offset;
2922         int counter;
2923         char *filename;
2924         int line;
2925         int column;
2926 } CoverageEntry;
2927
2928 static void
2929 free_coverage_entry (gpointer data, gpointer userdata)
2930 {
2931         CoverageEntry *entry = (CoverageEntry *)data;
2932         g_free (entry->filename);
2933         g_free (entry);
2934 }
2935
2936 static void
2937 obtain_coverage_for_method (MonoProfiler *prof, const MonoProfilerCoverageData *entry)
2938 {
2939         int offset = entry->il_offset - log_profiler.coverage_previous_offset;
2940         CoverageEntry *e = g_new (CoverageEntry, 1);
2941
2942         log_profiler.coverage_previous_offset = entry->il_offset;
2943
2944         e->offset = offset;
2945         e->counter = entry->counter;
2946         e->filename = g_strdup(entry->file_name ? entry->file_name : "");
2947         e->line = entry->line;
2948         e->column = entry->column;
2949
2950         g_ptr_array_add (log_profiler.coverage_data, e);
2951 }
2952
2953 static char *
2954 parse_generic_type_names(char *name)
2955 {
2956         char *new_name, *ret;
2957         int within_generic_declaration = 0, generic_members = 1;
2958
2959         if (name == NULL || *name == '\0')
2960                 return g_strdup ("");
2961
2962         if (!(ret = new_name = (char *) g_calloc (strlen (name) * 4 + 1, sizeof (char))))
2963                 return NULL;
2964
2965         do {
2966                 switch (*name) {
2967                         case '<':
2968                                 within_generic_declaration = 1;
2969                                 break;
2970
2971                         case '>':
2972                                 within_generic_declaration = 0;
2973
2974                                 if (*(name - 1) != '<') {
2975                                         *new_name++ = '`';
2976                                         *new_name++ = '0' + generic_members;
2977                                 } else {
2978                                         memcpy (new_name, "&lt;&gt;", 8);
2979                                         new_name += 8;
2980                                 }
2981
2982                                 generic_members = 0;
2983                                 break;
2984
2985                         case ',':
2986                                 generic_members++;
2987                                 break;
2988
2989                         default:
2990                                 if (!within_generic_declaration)
2991                                         *new_name++ = *name;
2992
2993                                 break;
2994                 }
2995         } while (*name++);
2996
2997         return ret;
2998 }
2999
3000 static void
3001 build_method_buffer (gpointer key, gpointer value, gpointer userdata)
3002 {
3003         MonoMethod *method = (MonoMethod *)value;
3004         MonoClass *klass;
3005         MonoImage *image;
3006         char *class_name;
3007         const char *image_name, *method_name, *sig, *first_filename;
3008         guint i;
3009
3010         log_profiler.coverage_previous_offset = 0;
3011         log_profiler.coverage_data = g_ptr_array_new ();
3012
3013         mono_profiler_get_coverage_data (log_profiler.handle, method, obtain_coverage_for_method);
3014
3015         klass = mono_method_get_class (method);
3016         image = mono_class_get_image (klass);
3017         image_name = mono_image_get_name (image);
3018
3019         sig = mono_signature_get_desc (mono_method_signature (method), TRUE);
3020         class_name = parse_generic_type_names (mono_type_get_name (mono_class_get_type (klass)));
3021         method_name = mono_method_get_name (method);
3022
3023         if (log_profiler.coverage_data->len != 0) {
3024                 CoverageEntry *entry = (CoverageEntry *)log_profiler.coverage_data->pdata[0];
3025                 first_filename = entry->filename ? entry->filename : "";
3026         } else
3027                 first_filename = "";
3028
3029         image_name = image_name ? image_name : "";
3030         sig = sig ? sig : "";
3031         method_name = method_name ? method_name : "";
3032
3033         ENTER_LOG (&coverage_methods_ctr, logbuffer,
3034                 EVENT_SIZE /* event */ +
3035                 strlen (image_name) + 1 /* image name */ +
3036                 strlen (class_name) + 1 /* class name */ +
3037                 strlen (method_name) + 1 /* method name */ +
3038                 strlen (sig) + 1 /* signature */ +
3039                 strlen (first_filename) + 1 /* first file name */ +
3040                 LEB128_SIZE /* token */ +
3041                 LEB128_SIZE /* method id */ +
3042                 LEB128_SIZE /* entries */
3043         );
3044
3045         emit_event (logbuffer, TYPE_COVERAGE_METHOD | TYPE_COVERAGE);
3046         emit_string (logbuffer, image_name, strlen (image_name) + 1);
3047         emit_string (logbuffer, class_name, strlen (class_name) + 1);
3048         emit_string (logbuffer, method_name, strlen (method_name) + 1);
3049         emit_string (logbuffer, sig, strlen (sig) + 1);
3050         emit_string (logbuffer, first_filename, strlen (first_filename) + 1);
3051
3052         emit_uvalue (logbuffer, mono_method_get_token (method));
3053         emit_uvalue (logbuffer, log_profiler.coverage_method_id);
3054         emit_value (logbuffer, log_profiler.coverage_data->len);
3055
3056         EXIT_LOG;
3057
3058         for (i = 0; i < log_profiler.coverage_data->len; i++) {
3059                 CoverageEntry *entry = (CoverageEntry *)log_profiler.coverage_data->pdata[i];
3060
3061                 ENTER_LOG (&coverage_statements_ctr, logbuffer,
3062                         EVENT_SIZE /* event */ +
3063                         LEB128_SIZE /* method id */ +
3064                         LEB128_SIZE /* offset */ +
3065                         LEB128_SIZE /* counter */ +
3066                         LEB128_SIZE /* line */ +
3067                         LEB128_SIZE /* column */
3068                 );
3069
3070                 emit_event (logbuffer, TYPE_COVERAGE_STATEMENT | TYPE_COVERAGE);
3071                 emit_uvalue (logbuffer, log_profiler.coverage_method_id);
3072                 emit_uvalue (logbuffer, entry->offset);
3073                 emit_uvalue (logbuffer, entry->counter);
3074                 emit_uvalue (logbuffer, entry->line);
3075                 emit_uvalue (logbuffer, entry->column);
3076
3077                 EXIT_LOG;
3078         }
3079
3080         log_profiler.coverage_method_id++;
3081
3082         g_free (class_name);
3083
3084         g_ptr_array_foreach (log_profiler.coverage_data, free_coverage_entry, NULL);
3085         g_ptr_array_free (log_profiler.coverage_data, TRUE);
3086 }
3087
3088 /* This empties the queue */
3089 static guint
3090 count_queue (MonoLockFreeQueue *queue)
3091 {
3092         MonoLockFreeQueueNode *node;
3093         guint count = 0;
3094
3095         while ((node = mono_lock_free_queue_dequeue (queue))) {
3096                 count++;
3097                 mono_thread_hazardous_try_free (node, g_free);
3098         }
3099
3100         return count;
3101 }
3102
3103 static void
3104 build_class_buffer (gpointer key, gpointer value, gpointer userdata)
3105 {
3106         MonoClass *klass = (MonoClass *)key;
3107         MonoLockFreeQueue *class_methods = (MonoLockFreeQueue *)value;
3108         MonoImage *image;
3109         char *class_name;
3110         const char *assembly_name;
3111         int number_of_methods, partially_covered;
3112         guint fully_covered;
3113
3114         image = mono_class_get_image (klass);
3115         assembly_name = mono_image_get_name (image);
3116         class_name = mono_type_get_name (mono_class_get_type (klass));
3117
3118         assembly_name = assembly_name ? assembly_name : "";
3119         number_of_methods = mono_class_num_methods (klass);
3120         fully_covered = count_queue (class_methods);
3121         /* We don't handle partial covered yet */
3122         partially_covered = 0;
3123
3124         ENTER_LOG (&coverage_classes_ctr, logbuffer,
3125                 EVENT_SIZE /* event */ +
3126                 strlen (assembly_name) + 1 /* assembly name */ +
3127                 strlen (class_name) + 1 /* class name */ +
3128                 LEB128_SIZE /* no. methods */ +
3129                 LEB128_SIZE /* fully covered */ +
3130                 LEB128_SIZE /* partially covered */
3131         );
3132
3133         emit_event (logbuffer, TYPE_COVERAGE_CLASS | TYPE_COVERAGE);
3134         emit_string (logbuffer, assembly_name, strlen (assembly_name) + 1);
3135         emit_string (logbuffer, class_name, strlen (class_name) + 1);
3136         emit_uvalue (logbuffer, number_of_methods);
3137         emit_uvalue (logbuffer, fully_covered);
3138         emit_uvalue (logbuffer, partially_covered);
3139
3140         EXIT_LOG;
3141
3142         g_free (class_name);
3143 }
3144
3145 static void
3146 get_coverage_for_image (MonoImage *image, int *number_of_methods, guint *fully_covered, int *partially_covered)
3147 {
3148         MonoLockFreeQueue *image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (log_profiler.coverage_image_to_methods, image);
3149
3150         *number_of_methods = mono_image_get_table_rows (image, MONO_TABLE_METHOD);
3151         if (image_methods)
3152                 *fully_covered = count_queue (image_methods);
3153         else
3154                 *fully_covered = 0;
3155
3156         // FIXME: We don't handle partially covered yet.
3157         *partially_covered = 0;
3158 }
3159
3160 static void
3161 build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
3162 {
3163         MonoAssembly *assembly = (MonoAssembly *)value;
3164         MonoImage *image = mono_assembly_get_image (assembly);
3165         const char *name, *guid, *filename;
3166         int number_of_methods = 0, partially_covered = 0;
3167         guint fully_covered = 0;
3168
3169         name = mono_image_get_name (image);
3170         guid = mono_image_get_guid (image);
3171         filename = mono_image_get_filename (image);
3172
3173         name = name ? name : "";
3174         guid = guid ? guid : "";
3175         filename = filename ? filename : "";
3176
3177         get_coverage_for_image (image, &number_of_methods, &fully_covered, &partially_covered);
3178
3179         ENTER_LOG (&coverage_assemblies_ctr, logbuffer,
3180                 EVENT_SIZE /* event */ +
3181                 strlen (name) + 1 /* name */ +
3182                 strlen (guid) + 1 /* guid */ +
3183                 strlen (filename) + 1 /* file name */ +
3184                 LEB128_SIZE /* no. methods */ +
3185                 LEB128_SIZE /* fully covered */ +
3186                 LEB128_SIZE /* partially covered */
3187         );
3188
3189         emit_event (logbuffer, TYPE_COVERAGE_ASSEMBLY | TYPE_COVERAGE);
3190         emit_string (logbuffer, name, strlen (name) + 1);
3191         emit_string (logbuffer, guid, strlen (guid) + 1);
3192         emit_string (logbuffer, filename, strlen (filename) + 1);
3193         emit_uvalue (logbuffer, number_of_methods);
3194         emit_uvalue (logbuffer, fully_covered);
3195         emit_uvalue (logbuffer, partially_covered);
3196
3197         EXIT_LOG;
3198 }
3199
3200 static void
3201 dump_coverage (void)
3202 {
3203         mono_os_mutex_lock (&log_profiler.coverage_mutex);
3204         mono_conc_hashtable_foreach (log_profiler.coverage_assemblies, build_assembly_buffer, NULL);
3205         mono_conc_hashtable_foreach (log_profiler.coverage_classes, build_class_buffer, NULL);
3206         mono_conc_hashtable_foreach (log_profiler.coverage_methods, build_method_buffer, NULL);
3207         mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3208 }
3209
3210 static MonoLockFreeQueueNode *
3211 create_method_node (MonoMethod *method)
3212 {
3213         MethodNode *node = (MethodNode *) g_malloc (sizeof (MethodNode));
3214         mono_lock_free_queue_node_init ((MonoLockFreeQueueNode *) node, FALSE);
3215         node->method = method;
3216
3217         return (MonoLockFreeQueueNode *) node;
3218 }
3219
3220 static gboolean
3221 coverage_filter (MonoProfiler *prof, MonoMethod *method)
3222 {
3223         MonoError error;
3224         MonoClass *klass;
3225         MonoImage *image;
3226         MonoAssembly *assembly;
3227         MonoMethodHeader *header;
3228         guint32 iflags, flags, code_size;
3229         char *fqn, *classname;
3230         gboolean has_positive, found;
3231         MonoLockFreeQueue *image_methods, *class_methods;
3232         MonoLockFreeQueueNode *node;
3233
3234         flags = mono_method_get_flags (method, &iflags);
3235         if ((iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
3236             (flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
3237                 return FALSE;
3238
3239         // Don't need to do anything else if we're already tracking this method
3240         if (mono_conc_hashtable_lookup (log_profiler.coverage_methods, method))
3241                 return TRUE;
3242
3243         klass = mono_method_get_class (method);
3244         image = mono_class_get_image (klass);
3245
3246         // Don't handle coverage for the core assemblies
3247         if (mono_conc_hashtable_lookup (log_profiler.coverage_suppressed_assemblies, (gpointer) mono_image_get_name (image)) != NULL)
3248                 return FALSE;
3249
3250         if (prof->coverage_filters) {
3251                 /* Check already filtered classes first */
3252                 if (mono_conc_hashtable_lookup (log_profiler.coverage_filtered_classes, klass))
3253                         return FALSE;
3254
3255                 classname = mono_type_get_name (mono_class_get_type (klass));
3256
3257                 fqn = g_strdup_printf ("[%s]%s", mono_image_get_name (image), classname);
3258
3259                 // Check positive filters first
3260                 has_positive = FALSE;
3261                 found = FALSE;
3262                 for (guint i = 0; i < prof->coverage_filters->len; ++i) {
3263                         char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
3264
3265                         if (filter [0] == '+') {
3266                                 filter = &filter [1];
3267
3268                                 if (strstr (fqn, filter) != NULL)
3269                                         found = TRUE;
3270
3271                                 has_positive = TRUE;
3272                         }
3273                 }
3274
3275                 if (has_positive && !found) {
3276                         mono_os_mutex_lock (&log_profiler.coverage_mutex);
3277                         mono_conc_hashtable_insert (log_profiler.coverage_filtered_classes, klass, klass);
3278                         mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3279                         g_free (fqn);
3280                         g_free (classname);
3281
3282                         return FALSE;
3283                 }
3284
3285                 for (guint i = 0; i < prof->coverage_filters->len; ++i) {
3286                         // FIXME: Is substring search sufficient?
3287                         char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
3288                         if (filter [0] == '+')
3289                                 continue;
3290
3291                         // Skip '-'
3292                         filter = &filter [1];
3293
3294                         if (strstr (fqn, filter) != NULL) {
3295                                 mono_os_mutex_lock (&log_profiler.coverage_mutex);
3296                                 mono_conc_hashtable_insert (log_profiler.coverage_filtered_classes, klass, klass);
3297                                 mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3298                                 g_free (fqn);
3299                                 g_free (classname);
3300
3301                                 return FALSE;
3302                         }
3303                 }
3304
3305                 g_free (fqn);
3306                 g_free (classname);
3307         }
3308
3309         header = mono_method_get_header_checked (method, &error);
3310         mono_error_cleanup (&error);
3311
3312         mono_method_header_get_code (header, &code_size, NULL);
3313
3314         assembly = mono_image_get_assembly (image);
3315
3316         // Need to keep the assemblies around for as long as they are kept in the hashtable
3317         // Nunit, for example, has a habit of unloading them before the coverage statistics are
3318         // generated causing a crash. See https://bugzilla.xamarin.com/show_bug.cgi?id=39325
3319         mono_assembly_addref (assembly);
3320
3321         mono_os_mutex_lock (&log_profiler.coverage_mutex);
3322         mono_conc_hashtable_insert (log_profiler.coverage_methods, method, method);
3323         mono_conc_hashtable_insert (log_profiler.coverage_assemblies, assembly, assembly);
3324         mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3325
3326         image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (log_profiler.coverage_image_to_methods, image);
3327
3328         if (image_methods == NULL) {
3329                 image_methods = (MonoLockFreeQueue *) g_malloc (sizeof (MonoLockFreeQueue));
3330                 mono_lock_free_queue_init (image_methods);
3331                 mono_os_mutex_lock (&log_profiler.coverage_mutex);
3332                 mono_conc_hashtable_insert (log_profiler.coverage_image_to_methods, image, image_methods);
3333                 mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3334         }
3335
3336         node = create_method_node (method);
3337         mono_lock_free_queue_enqueue (image_methods, node);
3338
3339         class_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (log_profiler.coverage_classes, klass);
3340
3341         if (class_methods == NULL) {
3342                 class_methods = (MonoLockFreeQueue *) g_malloc (sizeof (MonoLockFreeQueue));
3343                 mono_lock_free_queue_init (class_methods);
3344                 mono_os_mutex_lock (&log_profiler.coverage_mutex);
3345                 mono_conc_hashtable_insert (log_profiler.coverage_classes, klass, class_methods);
3346                 mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3347         }
3348
3349         node = create_method_node (method);
3350         mono_lock_free_queue_enqueue (class_methods, node);
3351
3352         return TRUE;
3353 }
3354
3355 #define LINE_BUFFER_SIZE 4096
3356 /* Max file limit of 128KB */
3357 #define MAX_FILE_SIZE 128 * 1024
3358 static char *
3359 get_file_content (FILE *stream)
3360 {
3361         char *buffer;
3362         ssize_t bytes_read;
3363         long filesize;
3364         int res, offset = 0;
3365
3366         res = fseek (stream, 0, SEEK_END);
3367         if (res < 0)
3368           return NULL;
3369
3370         filesize = ftell (stream);
3371         if (filesize < 0)
3372           return NULL;
3373
3374         res = fseek (stream, 0, SEEK_SET);
3375         if (res < 0)
3376           return NULL;
3377
3378         if (filesize > MAX_FILE_SIZE)
3379           return NULL;
3380
3381         buffer = (char *) g_malloc ((filesize + 1) * sizeof (char));
3382         while ((bytes_read = fread (buffer + offset, 1, LINE_BUFFER_SIZE, stream)) > 0)
3383                 offset += bytes_read;
3384
3385         /* NULL terminate our buffer */
3386         buffer[filesize] = '\0';
3387         return buffer;
3388 }
3389
3390 static char *
3391 get_next_line (char *contents, char **next_start)
3392 {
3393         char *p = contents;
3394
3395         if (p == NULL || *p == '\0') {
3396                 *next_start = NULL;
3397                 return NULL;
3398         }
3399
3400         while (*p != '\n' && *p != '\0')
3401                 p++;
3402
3403         if (*p == '\n') {
3404                 *p = '\0';
3405                 *next_start = p + 1;
3406         } else
3407                 *next_start = NULL;
3408
3409         return contents;
3410 }
3411
3412 static void
3413 init_suppressed_assemblies (void)
3414 {
3415         char *content;
3416         char *line;
3417         FILE *sa_file;
3418
3419         log_profiler.coverage_suppressed_assemblies = mono_conc_hashtable_new (g_str_hash, g_str_equal);
3420         sa_file = fopen (SUPPRESSION_DIR "/mono-profiler-log.suppression", "r");
3421         if (sa_file == NULL)
3422                 return;
3423
3424         /* Don't need to free @content as it is referred to by the lines stored in @suppressed_assemblies */
3425         content = get_file_content (sa_file);
3426         if (content == NULL)
3427                 g_error ("mono-profiler-log.suppression is greater than 128kb - aborting.");
3428
3429         while ((line = get_next_line (content, &content))) {
3430                 line = g_strchomp (g_strchug (line));
3431                 /* No locking needed as we're doing initialization */
3432                 mono_conc_hashtable_insert (log_profiler.coverage_suppressed_assemblies, line, line);
3433         }
3434
3435         fclose (sa_file);
3436 }
3437
3438 static void
3439 parse_cov_filter_file (GPtrArray *filters, const char *file)
3440 {
3441         FILE *filter_file = fopen (file, "r");
3442
3443         if (filter_file == NULL) {
3444                 mono_profiler_printf_err ("Could not open coverage filter file '%s'.", file);
3445                 return;
3446         }
3447
3448         /* Don't need to free content as it is referred to by the lines stored in @filters */
3449         char *content = get_file_content (filter_file);
3450
3451         if (content == NULL)
3452                 mono_profiler_printf_err ("Coverage filter file '%s' is larger than 128kb - ignoring.", file);
3453
3454         char *line;
3455
3456         while ((line = get_next_line (content, &content)))
3457                 g_ptr_array_add (filters, g_strchug (g_strchomp (line)));
3458
3459         fclose (filter_file);
3460 }
3461
3462 static void
3463 coverage_init (void)
3464 {
3465         mono_os_mutex_init (&log_profiler.coverage_mutex);
3466         log_profiler.coverage_methods = mono_conc_hashtable_new (NULL, NULL);
3467         log_profiler.coverage_assemblies = mono_conc_hashtable_new (NULL, NULL);
3468         log_profiler.coverage_classes = mono_conc_hashtable_new (NULL, NULL);
3469         log_profiler.coverage_filtered_classes = mono_conc_hashtable_new (NULL, NULL);
3470         log_profiler.coverage_image_to_methods = mono_conc_hashtable_new (NULL, NULL);
3471         init_suppressed_assemblies ();
3472 }
3473
3474 static void
3475 unref_coverage_assemblies (gpointer key, gpointer value, gpointer userdata)
3476 {
3477         MonoAssembly *assembly = (MonoAssembly *)value;
3478         mono_assembly_close (assembly);
3479 }
3480
3481 static void
3482 free_sample_hit (gpointer p)
3483 {
3484         mono_lock_free_free (p, SAMPLE_BLOCK_SIZE);
3485 }
3486
3487 static void
3488 cleanup_reusable_samples (void)
3489 {
3490         SampleHit *sample;
3491
3492         while ((sample = (SampleHit *) mono_lock_free_queue_dequeue (&log_profiler.sample_reuse_queue)))
3493                 mono_thread_hazardous_try_free (sample, free_sample_hit);
3494 }
3495
3496 static void
3497 log_early_shutdown (MonoProfiler *prof)
3498 {
3499         if (log_config.hs_on_shutdown) {
3500                 InterlockedWrite (&log_profiler.heapshot_requested, 1);
3501                 mono_gc_collect (mono_gc_max_generation ());
3502         }
3503 }
3504
3505 static void
3506 log_shutdown (MonoProfiler *prof)
3507 {
3508         InterlockedWrite (&log_profiler.in_shutdown, 1);
3509
3510         if (ENABLED (PROFLOG_COUNTER_EVENTS))
3511                 counters_and_perfcounters_sample ();
3512
3513         if (log_config.collect_coverage)
3514                 dump_coverage ();
3515
3516         char c = 1;
3517
3518         if (write (prof->pipes [1], &c, 1) != 1) {
3519                 mono_profiler_printf_err ("Could not write to log profiler pipe: %s", strerror (errno));
3520                 exit (1);
3521         }
3522
3523         mono_native_thread_join (prof->helper_thread);
3524
3525         mono_os_mutex_destroy (&log_profiler.counters_mutex);
3526
3527         MonoCounterAgent *mc_next;
3528
3529         for (MonoCounterAgent *cur = log_profiler.counters; cur; cur = mc_next) {
3530                 mc_next = cur->next;
3531                 g_free (cur);
3532         }
3533
3534         PerfCounterAgent *pc_next;
3535
3536         for (PerfCounterAgent *cur = log_profiler.perfcounters; cur; cur = pc_next) {
3537                 pc_next = cur->next;
3538                 g_free (cur);
3539         }
3540
3541         /*
3542          * Ensure that we empty the LLS completely, even if some nodes are
3543          * not immediately removed upon calling mono_lls_remove (), by
3544          * iterating until the head is NULL.
3545          */
3546         while (log_profiler.profiler_thread_list.head) {
3547                 MONO_LLS_FOREACH_SAFE (&log_profiler.profiler_thread_list, MonoProfilerThread, thread) {
3548                         g_assert (thread->attached && "Why is a thread in the LLS not attached?");
3549
3550                         remove_thread (thread);
3551                 } MONO_LLS_FOREACH_SAFE_END
3552         }
3553
3554         /*
3555          * Ensure that all threads have been freed, so that we don't miss any
3556          * buffers when we shut down the writer thread below.
3557          */
3558         mono_thread_hazardous_try_free_all ();
3559
3560         InterlockedWrite (&prof->run_dumper_thread, 0);
3561         mono_os_sem_post (&prof->dumper_queue_sem);
3562         mono_native_thread_join (prof->dumper_thread);
3563         mono_os_sem_destroy (&prof->dumper_queue_sem);
3564
3565         InterlockedWrite (&prof->run_writer_thread, 0);
3566         mono_os_sem_post (&prof->writer_queue_sem);
3567         mono_native_thread_join (prof->writer_thread);
3568         mono_os_sem_destroy (&prof->writer_queue_sem);
3569
3570         /*
3571          * Free all writer queue entries, and ensure that all sample hits will be
3572          * added to the sample reuse queue.
3573          */
3574         mono_thread_hazardous_try_free_all ();
3575
3576         cleanup_reusable_samples ();
3577
3578         /*
3579          * Finally, make sure that all sample hits are freed. This should cover all
3580          * hazardous data from the profiler. We can now be sure that the runtime
3581          * won't later invoke free functions in the profiler library after it has
3582          * been unloaded.
3583          */
3584         mono_thread_hazardous_try_free_all ();
3585
3586         gint32 state = InterlockedRead (&log_profiler.buffer_lock_state);
3587
3588         g_assert (!(state & 0xFFFF) && "Why is the reader count still non-zero?");
3589         g_assert (!(state >> 16) && "Why is the exclusive lock still held?");
3590
3591 #if defined (HAVE_SYS_ZLIB)
3592         if (prof->gzfile)
3593                 gzclose (prof->gzfile);
3594 #endif
3595         if (prof->pipe_output)
3596                 pclose (prof->file);
3597         else
3598                 fclose (prof->file);
3599
3600         mono_conc_hashtable_destroy (prof->method_table);
3601         mono_os_mutex_destroy (&prof->method_table_mutex);
3602
3603         if (log_config.collect_coverage) {
3604                 mono_os_mutex_lock (&log_profiler.coverage_mutex);
3605                 mono_conc_hashtable_foreach (log_profiler.coverage_assemblies, unref_coverage_assemblies, NULL);
3606                 mono_os_mutex_unlock (&log_profiler.coverage_mutex);
3607
3608                 mono_conc_hashtable_destroy (log_profiler.coverage_methods);
3609                 mono_conc_hashtable_destroy (log_profiler.coverage_assemblies);
3610                 mono_conc_hashtable_destroy (log_profiler.coverage_classes);
3611                 mono_conc_hashtable_destroy (log_profiler.coverage_filtered_classes);
3612
3613                 mono_conc_hashtable_destroy (log_profiler.coverage_image_to_methods);
3614                 mono_conc_hashtable_destroy (log_profiler.coverage_suppressed_assemblies);
3615                 mono_os_mutex_destroy (&log_profiler.coverage_mutex);
3616         }
3617
3618         PROF_TLS_FREE ();
3619
3620         g_free (prof->args);
3621 }
3622
3623 static char*
3624 new_filename (const char* filename)
3625 {
3626         time_t t = time (NULL);
3627         int pid = process_id ();
3628         char pid_buf [16];
3629         char time_buf [16];
3630         char *res, *d;
3631         const char *p;
3632         int count_dates = 0;
3633         int count_pids = 0;
3634         int s_date, s_pid;
3635         struct tm *ts;
3636         for (p = filename; *p; p++) {
3637                 if (*p != '%')
3638                         continue;
3639                 p++;
3640                 if (*p == 't')
3641                         count_dates++;
3642                 else if (*p == 'p')
3643                         count_pids++;
3644                 else if (*p == 0)
3645                         break;
3646         }
3647         if (!count_dates && !count_pids)
3648                 return pstrdup (filename);
3649         snprintf (pid_buf, sizeof (pid_buf), "%d", pid);
3650         ts = gmtime (&t);
3651         snprintf (time_buf, sizeof (time_buf), "%d%02d%02d%02d%02d%02d",
3652                 1900 + ts->tm_year, 1 + ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec);
3653         s_date = strlen (time_buf);
3654         s_pid = strlen (pid_buf);
3655         d = res = (char *) g_malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids);
3656         for (p = filename; *p; p++) {
3657                 if (*p != '%') {
3658                         *d++ = *p;
3659                         continue;
3660                 }
3661                 p++;
3662                 if (*p == 't') {
3663                         strcpy (d, time_buf);
3664                         d += s_date;
3665                         continue;
3666                 } else if (*p == 'p') {
3667                         strcpy (d, pid_buf);
3668                         d += s_pid;
3669                         continue;
3670                 } else if (*p == '%') {
3671                         *d++ = '%';
3672                         continue;
3673                 } else if (*p == 0)
3674                         break;
3675                 *d++ = '%';
3676                 *d++ = *p;
3677         }
3678         *d = 0;
3679         return res;
3680 }
3681
3682 static void
3683 add_to_fd_set (fd_set *set, int fd, int *max_fd)
3684 {
3685         /*
3686          * This should only trigger for the basic FDs (server socket, pipes) at
3687          * startup if for some mysterious reason they're too large. In this case,
3688          * the profiler really can't function, and we're better off printing an
3689          * error and exiting.
3690          */
3691         if (fd >= FD_SETSIZE) {
3692                 mono_profiler_printf_err ("File descriptor is out of bounds for fd_set: %d", fd);
3693                 exit (1);
3694         }
3695
3696         FD_SET (fd, set);
3697
3698         if (*max_fd < fd)
3699                 *max_fd = fd;
3700 }
3701
3702 static void *
3703 helper_thread (void *arg)
3704 {
3705         mono_threads_attach_tools_thread ();
3706         mono_native_thread_set_name (mono_native_thread_id_get (), "Profiler helper");
3707
3708         MonoProfilerThread *thread = init_thread (FALSE);
3709
3710         GArray *command_sockets = g_array_new (FALSE, FALSE, sizeof (int));
3711
3712         while (1) {
3713                 fd_set rfds;
3714                 int max_fd = -1;
3715
3716                 FD_ZERO (&rfds);
3717
3718                 add_to_fd_set (&rfds, log_profiler.server_socket, &max_fd);
3719                 add_to_fd_set (&rfds, log_profiler.pipes [0], &max_fd);
3720
3721                 for (gint i = 0; i < command_sockets->len; i++)
3722                         add_to_fd_set (&rfds, g_array_index (command_sockets, int, i), &max_fd);
3723
3724                 struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
3725
3726                 // Sleep for 1sec or until a file descriptor has data.
3727                 if (select (max_fd + 1, &rfds, NULL, NULL, &tv) == -1) {
3728                         if (errno == EINTR)
3729                                 continue;
3730
3731                         mono_profiler_printf_err ("Could not poll in log profiler helper thread: %s", strerror (errno));
3732                         exit (1);
3733                 }
3734
3735                 if (ENABLED (PROFLOG_COUNTER_EVENTS))
3736                         counters_and_perfcounters_sample ();
3737
3738                 buffer_lock_excl ();
3739
3740                 sync_point (SYNC_POINT_PERIODIC);
3741
3742                 buffer_unlock_excl ();
3743
3744                 // Are we shutting down?
3745                 if (FD_ISSET (log_profiler.pipes [0], &rfds)) {
3746                         char c;
3747                         read (log_profiler.pipes [0], &c, 1);
3748                         break;
3749                 }
3750
3751                 for (gint i = 0; i < command_sockets->len; i++) {
3752                         int fd = g_array_index (command_sockets, int, i);
3753
3754                         if (!FD_ISSET (fd, &rfds))
3755                                 continue;
3756
3757                         char buf [64];
3758                         int len = read (fd, buf, sizeof (buf) - 1);
3759
3760                         if (len == -1)
3761                                 continue;
3762
3763                         if (!len) {
3764                                 // The other end disconnected.
3765                                 g_array_remove_index (command_sockets, i);
3766                                 close (fd);
3767
3768                                 continue;
3769                         }
3770
3771                         buf [len] = 0;
3772
3773                         if (log_config.hs_mode == MONO_PROFILER_HEAPSHOT_ON_DEMAND && !strcmp (buf, "heapshot\n")) {
3774                                 // Rely on the finalization callback triggering a GC.
3775                                 InterlockedWrite (&log_profiler.heapshot_requested, 1);
3776                                 mono_gc_finalize_notify ();
3777                         }
3778                 }
3779
3780                 if (FD_ISSET (log_profiler.server_socket, &rfds)) {
3781                         int fd = accept (log_profiler.server_socket, NULL, NULL);
3782
3783                         if (fd != -1) {
3784                                 if (fd >= FD_SETSIZE)
3785                                         close (fd);
3786                                 else
3787                                         g_array_append_val (command_sockets, fd);
3788                         }
3789                 }
3790         }
3791
3792         for (gint i = 0; i < command_sockets->len; i++)
3793                 close (g_array_index (command_sockets, int, i));
3794
3795         g_array_free (command_sockets, TRUE);
3796
3797         send_log_unsafe (FALSE);
3798         deinit_thread (thread);
3799
3800         mono_thread_info_detach ();
3801
3802         return NULL;
3803 }
3804
3805 static void
3806 start_helper_thread (void)
3807 {
3808         if (pipe (log_profiler.pipes) == -1) {
3809                 mono_profiler_printf_err ("Could not create log profiler pipe: %s", strerror (errno));
3810                 exit (1);
3811         }
3812
3813         log_profiler.server_socket = socket (PF_INET, SOCK_STREAM, 0);
3814
3815         if (log_profiler.server_socket == -1) {
3816                 mono_profiler_printf_err ("Could not create log profiler server socket: %s", strerror (errno));
3817                 exit (1);
3818         }
3819
3820         struct sockaddr_in server_address;
3821
3822         memset (&server_address, 0, sizeof (server_address));
3823         server_address.sin_family = AF_INET;
3824         server_address.sin_addr.s_addr = INADDR_ANY;
3825         server_address.sin_port = htons (log_profiler.command_port);
3826
3827         if (bind (log_profiler.server_socket, (struct sockaddr *) &server_address, sizeof (server_address)) == -1) {
3828                 mono_profiler_printf_err ("Could not bind log profiler server socket on port %d: %s", log_profiler.command_port, strerror (errno));
3829                 close (log_profiler.server_socket);
3830                 exit (1);
3831         }
3832
3833         if (listen (log_profiler.server_socket, 1) == -1) {
3834                 mono_profiler_printf_err ("Could not listen on log profiler server socket: %s", strerror (errno));
3835                 close (log_profiler.server_socket);
3836                 exit (1);
3837         }
3838
3839         socklen_t slen = sizeof (server_address);
3840
3841         if (getsockname (log_profiler.server_socket, (struct sockaddr *) &server_address, &slen)) {
3842                 mono_profiler_printf_err ("Could not retrieve assigned port for log profiler server socket: %s", strerror (errno));
3843                 close (log_profiler.server_socket);
3844                 exit (1);
3845         }
3846
3847         log_profiler.command_port = ntohs (server_address.sin_port);
3848
3849         if (!mono_native_thread_create (&log_profiler.helper_thread, helper_thread, NULL)) {
3850                 mono_profiler_printf_err ("Could not start log profiler helper thread");
3851                 close (log_profiler.server_socket);
3852                 exit (1);
3853         }
3854 }
3855
3856 static void
3857 free_writer_entry (gpointer p)
3858 {
3859         mono_lock_free_free (p, WRITER_ENTRY_BLOCK_SIZE);
3860 }
3861
3862 static gboolean
3863 handle_writer_queue_entry (void)
3864 {
3865         WriterQueueEntry *entry;
3866
3867         if ((entry = (WriterQueueEntry *) mono_lock_free_queue_dequeue (&log_profiler.writer_queue))) {
3868                 if (!entry->methods)
3869                         goto no_methods;
3870
3871                 gboolean wrote_methods = FALSE;
3872
3873                 /*
3874                  * Encode the method events in a temporary log buffer that we
3875                  * flush to disk before the main buffer, ensuring that all
3876                  * methods have metadata emitted before they're referenced.
3877                  *
3878                  * We use a 'proper' thread-local buffer for this as opposed
3879                  * to allocating and freeing a buffer by hand because the call
3880                  * to mono_method_full_name () below may trigger class load
3881                  * events when it retrieves the signature of the method. So a
3882                  * thread-local buffer needs to exist when such events occur.
3883                  */
3884                 for (guint i = 0; i < entry->methods->len; i++) {
3885                         MethodInfo *info = (MethodInfo *) g_ptr_array_index (entry->methods, i);
3886
3887                         if (mono_conc_hashtable_lookup (log_profiler.method_table, info->method))
3888                                 goto free_info; // This method already has metadata emitted.
3889
3890                         /*
3891                          * Other threads use this hash table to get a general
3892                          * idea of whether a method has already been emitted to
3893                          * the stream. Due to the way we add to this table, it
3894                          * can easily happen that multiple threads queue up the
3895                          * same methods, but that's OK since eventually all
3896                          * methods will be in this table and the thread-local
3897                          * method lists will just be empty for the rest of the
3898                          * app's lifetime.
3899                          */
3900                         mono_os_mutex_lock (&log_profiler.method_table_mutex);
3901                         mono_conc_hashtable_insert (log_profiler.method_table, info->method, info->method);
3902                         mono_os_mutex_unlock (&log_profiler.method_table_mutex);
3903
3904                         char *name = mono_method_full_name (info->method, 1);
3905                         int nlen = strlen (name) + 1;
3906                         void *cstart = info->ji ? mono_jit_info_get_code_start (info->ji) : NULL;
3907                         int csize = info->ji ? mono_jit_info_get_code_size (info->ji) : 0;
3908
3909                         ENTER_LOG (&method_jits_ctr, logbuffer,
3910                                 EVENT_SIZE /* event */ +
3911                                 LEB128_SIZE /* method */ +
3912                                 LEB128_SIZE /* start */ +
3913                                 LEB128_SIZE /* size */ +
3914                                 nlen /* name */
3915                         );
3916
3917                         emit_event_time (logbuffer, TYPE_JIT | TYPE_METHOD, info->time);
3918                         emit_method_inner (logbuffer, info->method);
3919                         emit_ptr (logbuffer, cstart);
3920                         emit_value (logbuffer, csize);
3921
3922                         memcpy (logbuffer->cursor, name, nlen);
3923                         logbuffer->cursor += nlen;
3924
3925                         EXIT_LOG_EXPLICIT (NO_SEND);
3926
3927                         mono_free (name);
3928
3929                         wrote_methods = TRUE;
3930
3931                 free_info:
3932                         g_free (info);
3933                 }
3934
3935                 g_ptr_array_free (entry->methods, TRUE);
3936
3937                 if (wrote_methods) {
3938                         MonoProfilerThread *thread = PROF_TLS_GET ();
3939
3940                         dump_buffer_threadless (thread->buffer);
3941                         init_buffer_state (thread);
3942                 }
3943
3944         no_methods:
3945                 dump_buffer (entry->buffer);
3946
3947                 mono_thread_hazardous_try_free (entry, free_writer_entry);
3948
3949                 return TRUE;
3950         }
3951
3952         return FALSE;
3953 }
3954
3955 static void *
3956 writer_thread (void *arg)
3957 {
3958         mono_threads_attach_tools_thread ();
3959         mono_native_thread_set_name (mono_native_thread_id_get (), "Profiler writer");
3960
3961         dump_header ();
3962
3963         MonoProfilerThread *thread = init_thread (FALSE);
3964
3965         while (InterlockedRead (&log_profiler.run_writer_thread)) {
3966                 mono_os_sem_wait (&log_profiler.writer_queue_sem, MONO_SEM_FLAGS_NONE);
3967                 handle_writer_queue_entry ();
3968         }
3969
3970         /* Drain any remaining entries on shutdown. */
3971         while (handle_writer_queue_entry ());
3972
3973         free_buffer (thread->buffer, thread->buffer->size);
3974         deinit_thread (thread);
3975
3976         mono_thread_info_detach ();
3977
3978         return NULL;
3979 }
3980
3981 static void
3982 start_writer_thread (void)
3983 {
3984         InterlockedWrite (&log_profiler.run_writer_thread, 1);
3985
3986         if (!mono_native_thread_create (&log_profiler.writer_thread, writer_thread, NULL)) {
3987                 mono_profiler_printf_err ("Could not start log profiler writer thread");
3988                 exit (1);
3989         }
3990 }
3991
3992 static void
3993 reuse_sample_hit (gpointer p)
3994 {
3995         SampleHit *sample = p;
3996
3997         mono_lock_free_queue_node_unpoison (&sample->node);
3998         mono_lock_free_queue_enqueue (&log_profiler.sample_reuse_queue, &sample->node);
3999 }
4000
4001 static gboolean
4002 handle_dumper_queue_entry (void)
4003 {
4004         SampleHit *sample;
4005
4006         if ((sample = (SampleHit *) mono_lock_free_queue_dequeue (&log_profiler.dumper_queue))) {
4007                 for (int i = 0; i < sample->count; ++i) {
4008                         MonoMethod *method = sample->frames [i].method;
4009                         MonoDomain *domain = sample->frames [i].domain;
4010                         void *address = sample->frames [i].base_address;
4011
4012                         if (!method) {
4013                                 g_assert (domain && "What happened to the domain pointer?");
4014                                 g_assert (address && "What happened to the instruction pointer?");
4015
4016                                 MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *) address);
4017
4018                                 if (ji)
4019                                         sample->frames [i].method = mono_jit_info_get_method (ji);
4020                         }
4021                 }
4022
4023                 ENTER_LOG (&sample_hits_ctr, logbuffer,
4024                         EVENT_SIZE /* event */ +
4025                         LEB128_SIZE /* tid */ +
4026                         LEB128_SIZE /* count */ +
4027                         1 * (
4028                                 LEB128_SIZE /* ip */
4029                         ) +
4030                         LEB128_SIZE /* managed count */ +
4031                         sample->count * (
4032                                 LEB128_SIZE /* method */
4033                         )
4034                 );
4035
4036                 emit_event_time (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT, sample->time);
4037                 emit_ptr (logbuffer, (void *) sample->tid);
4038                 emit_value (logbuffer, 1);
4039
4040                 // TODO: Actual native unwinding.
4041                 for (int i = 0; i < 1; ++i) {
4042                         emit_ptr (logbuffer, sample->ip);
4043                         add_code_pointer ((uintptr_t) sample->ip);
4044                 }
4045
4046                 /* new in data version 6 */
4047                 emit_uvalue (logbuffer, sample->count);
4048
4049                 for (int i = 0; i < sample->count; ++i)
4050                         emit_method (logbuffer, sample->frames [i].method);
4051
4052                 EXIT_LOG;
4053
4054                 mono_thread_hazardous_try_free (sample, reuse_sample_hit);
4055
4056                 dump_unmanaged_coderefs ();
4057         }
4058
4059         return FALSE;
4060 }
4061
4062 static void *
4063 dumper_thread (void *arg)
4064 {
4065         mono_threads_attach_tools_thread ();
4066         mono_native_thread_set_name (mono_native_thread_id_get (), "Profiler dumper");
4067
4068         MonoProfilerThread *thread = init_thread (FALSE);
4069
4070         while (InterlockedRead (&log_profiler.run_dumper_thread)) {
4071                 /*
4072                  * Flush samples every second so it doesn't seem like the profiler is
4073                  * not working if the program is mostly idle.
4074                  */
4075                 if (mono_os_sem_timedwait (&log_profiler.dumper_queue_sem, 1000, MONO_SEM_FLAGS_NONE) == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT)
4076                         send_log_unsafe (FALSE);
4077
4078                 handle_dumper_queue_entry ();
4079         }
4080
4081         /* Drain any remaining entries on shutdown. */
4082         while (handle_dumper_queue_entry ());
4083
4084         send_log_unsafe (FALSE);
4085         deinit_thread (thread);
4086
4087         mono_thread_info_detach ();
4088
4089         return NULL;
4090 }
4091
4092 static void
4093 start_dumper_thread (void)
4094 {
4095         InterlockedWrite (&log_profiler.run_dumper_thread, 1);
4096
4097         if (!mono_native_thread_create (&log_profiler.dumper_thread, dumper_thread, NULL)) {
4098                 mono_profiler_printf_err ("Could not start log profiler dumper thread");
4099                 exit (1);
4100         }
4101 }
4102
4103 static void
4104 register_counter (const char *name, gint32 *counter)
4105 {
4106         mono_counters_register (name, MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, counter);
4107 }
4108
4109 static void
4110 runtime_initialized (MonoProfiler *profiler)
4111 {
4112         InterlockedWrite (&log_profiler.runtime_inited, 1);
4113
4114         register_counter ("Sample events allocated", &sample_allocations_ctr);
4115         register_counter ("Log buffers allocated", &buffer_allocations_ctr);
4116
4117         register_counter ("Event: Sync points", &sync_points_ctr);
4118         register_counter ("Event: Heap objects", &heap_objects_ctr);
4119         register_counter ("Event: Heap starts", &heap_starts_ctr);
4120         register_counter ("Event: Heap ends", &heap_ends_ctr);
4121         register_counter ("Event: Heap roots", &heap_roots_ctr);
4122         register_counter ("Event: GC events", &gc_events_ctr);
4123         register_counter ("Event: GC resizes", &gc_resizes_ctr);
4124         register_counter ("Event: GC allocations", &gc_allocs_ctr);
4125         register_counter ("Event: GC moves", &gc_moves_ctr);
4126         register_counter ("Event: GC handle creations", &gc_handle_creations_ctr);
4127         register_counter ("Event: GC handle deletions", &gc_handle_deletions_ctr);
4128         register_counter ("Event: GC finalize starts", &finalize_begins_ctr);
4129         register_counter ("Event: GC finalize ends", &finalize_ends_ctr);
4130         register_counter ("Event: GC finalize object starts", &finalize_object_begins_ctr);
4131         register_counter ("Event: GC finalize object ends", &finalize_object_ends_ctr);
4132         register_counter ("Event: Image loads", &image_loads_ctr);
4133         register_counter ("Event: Image unloads", &image_unloads_ctr);
4134         register_counter ("Event: Assembly loads", &assembly_loads_ctr);
4135         register_counter ("Event: Assembly unloads", &assembly_unloads_ctr);
4136         register_counter ("Event: Class loads", &class_loads_ctr);
4137         register_counter ("Event: Class unloads", &class_unloads_ctr);
4138         register_counter ("Event: Method entries", &method_entries_ctr);
4139         register_counter ("Event: Method exits", &method_exits_ctr);
4140         register_counter ("Event: Method exception leaves", &method_exception_exits_ctr);
4141         register_counter ("Event: Method JITs", &method_jits_ctr);
4142         register_counter ("Event: Code buffers", &code_buffers_ctr);
4143         register_counter ("Event: Exception throws", &exception_throws_ctr);
4144         register_counter ("Event: Exception clauses", &exception_clauses_ctr);
4145         register_counter ("Event: Monitor events", &monitor_events_ctr);
4146         register_counter ("Event: Thread starts", &thread_starts_ctr);
4147         register_counter ("Event: Thread ends", &thread_ends_ctr);
4148         register_counter ("Event: Thread names", &thread_names_ctr);
4149         register_counter ("Event: Domain loads", &domain_loads_ctr);
4150         register_counter ("Event: Domain unloads", &domain_unloads_ctr);
4151         register_counter ("Event: Domain names", &domain_names_ctr);
4152         register_counter ("Event: Context loads", &context_loads_ctr);
4153         register_counter ("Event: Context unloads", &context_unloads_ctr);
4154         register_counter ("Event: Sample binaries", &sample_ubins_ctr);
4155         register_counter ("Event: Sample symbols", &sample_usyms_ctr);
4156         register_counter ("Event: Sample hits", &sample_hits_ctr);
4157         register_counter ("Event: Counter descriptors", &counter_descriptors_ctr);
4158         register_counter ("Event: Counter samples", &counter_samples_ctr);
4159         register_counter ("Event: Performance counter descriptors", &perfcounter_descriptors_ctr);
4160         register_counter ("Event: Performance counter samples", &perfcounter_samples_ctr);
4161         register_counter ("Event: Coverage methods", &coverage_methods_ctr);
4162         register_counter ("Event: Coverage statements", &coverage_statements_ctr);
4163         register_counter ("Event: Coverage classes", &coverage_classes_ctr);
4164         register_counter ("Event: Coverage assemblies", &coverage_assemblies_ctr);
4165
4166         counters_init ();
4167
4168         /*
4169          * We must start the helper thread before the writer thread. This is
4170          * because the helper thread sets up the command port which is written to
4171          * the log header by the writer thread.
4172          */
4173         start_helper_thread ();
4174         start_writer_thread ();
4175         start_dumper_thread ();
4176 }
4177
4178 static void
4179 create_profiler (const char *args, const char *filename, GPtrArray *filters)
4180 {
4181         char *nf;
4182
4183         log_profiler.args = pstrdup (args);
4184         log_profiler.command_port = log_config.command_port;
4185
4186         //If filename begin with +, append the pid at the end
4187         if (filename && *filename == '+')
4188                 filename = g_strdup_printf ("%s.%d", filename + 1, getpid ());
4189
4190         if (!filename) {
4191                 if (log_config.do_report)
4192                         filename = "|mprof-report -";
4193                 else
4194                         filename = "output.mlpd";
4195                 nf = (char*)filename;
4196         } else {
4197                 nf = new_filename (filename);
4198                 if (log_config.do_report) {
4199                         int s = strlen (nf) + 32;
4200                         char *p = (char *) g_malloc (s);
4201                         snprintf (p, s, "|mprof-report '--out=%s' -", nf);
4202                         g_free (nf);
4203                         nf = p;
4204                 }
4205         }
4206         if (*nf == '|') {
4207                 log_profiler.file = popen (nf + 1, "w");
4208                 log_profiler.pipe_output = 1;
4209         } else if (*nf == '#') {
4210                 int fd = strtol (nf + 1, NULL, 10);
4211                 log_profiler.file = fdopen (fd, "a");
4212         } else
4213                 log_profiler.file = fopen (nf, "wb");
4214
4215         if (!log_profiler.file) {
4216                 mono_profiler_printf_err ("Could not create log profiler output file '%s'.", nf);
4217                 exit (1);
4218         }
4219
4220 #if defined (HAVE_SYS_ZLIB)
4221         if (log_config.use_zip)
4222                 log_profiler.gzfile = gzdopen (fileno (log_profiler.file), "wb");
4223 #endif
4224
4225         /*
4226          * If you hit this assert while increasing MAX_FRAMES, you need to increase
4227          * SAMPLE_BLOCK_SIZE as well.
4228          */
4229         g_assert (SAMPLE_SLOT_SIZE (MAX_FRAMES) * 2 < LOCK_FREE_ALLOC_SB_USABLE_SIZE (SAMPLE_BLOCK_SIZE));
4230
4231         // FIXME: We should free this stuff too.
4232         mono_lock_free_allocator_init_size_class (&log_profiler.sample_size_class, SAMPLE_SLOT_SIZE (log_config.num_frames), SAMPLE_BLOCK_SIZE);
4233         mono_lock_free_allocator_init_allocator (&log_profiler.sample_allocator, &log_profiler.sample_size_class, MONO_MEM_ACCOUNT_PROFILER);
4234
4235         mono_lock_free_queue_init (&log_profiler.sample_reuse_queue);
4236
4237         g_assert (sizeof (WriterQueueEntry) * 2 < LOCK_FREE_ALLOC_SB_USABLE_SIZE (WRITER_ENTRY_BLOCK_SIZE));
4238
4239         // FIXME: We should free this stuff too.
4240         mono_lock_free_allocator_init_size_class (&log_profiler.writer_entry_size_class, sizeof (WriterQueueEntry), WRITER_ENTRY_BLOCK_SIZE);
4241         mono_lock_free_allocator_init_allocator (&log_profiler.writer_entry_allocator, &log_profiler.writer_entry_size_class, MONO_MEM_ACCOUNT_PROFILER);
4242
4243         mono_lock_free_queue_init (&log_profiler.writer_queue);
4244         mono_os_sem_init (&log_profiler.writer_queue_sem, 0);
4245
4246         mono_lock_free_queue_init (&log_profiler.dumper_queue);
4247         mono_os_sem_init (&log_profiler.dumper_queue_sem, 0);
4248
4249         mono_os_mutex_init (&log_profiler.method_table_mutex);
4250         log_profiler.method_table = mono_conc_hashtable_new (NULL, NULL);
4251
4252         if (log_config.collect_coverage)
4253                 coverage_init ();
4254
4255         log_profiler.coverage_filters = filters;
4256
4257         log_profiler.startup_time = current_time ();
4258 }
4259
4260 /*
4261  * declaration to silence the compiler: this is the entry point that
4262  * mono will load from the shared library and call.
4263  */
4264 extern void
4265 mono_profiler_init (const char *desc);
4266
4267 extern void
4268 mono_profiler_init_log (const char *desc);
4269
4270 /*
4271  * this is the entry point that will be used when the profiler
4272  * is embedded inside the main executable.
4273  */
4274 void
4275 mono_profiler_init_log (const char *desc)
4276 {
4277         mono_profiler_init (desc);
4278 }
4279
4280 void
4281 mono_profiler_init (const char *desc)
4282 {
4283         GPtrArray *filters = NULL;
4284
4285         proflog_parse_args (&log_config, desc [3] == ':' ? desc + 4 : "");
4286
4287         if (log_config.cov_filter_files) {
4288                 filters = g_ptr_array_new ();
4289                 int i;
4290                 for (i = 0; i < log_config.cov_filter_files->len; ++i) {
4291                         const char *name = log_config.cov_filter_files->pdata [i];
4292                         parse_cov_filter_file (filters, name);
4293                 }
4294         }
4295
4296         init_time ();
4297
4298         PROF_TLS_INIT ();
4299
4300         create_profiler (desc, log_config.output_filename, filters);
4301
4302         mono_lls_init (&log_profiler.profiler_thread_list, NULL);
4303
4304         MonoProfilerHandle handle = log_profiler.handle = mono_profiler_install (&log_profiler);
4305
4306         /*
4307          * Required callbacks. These are either necessary for the profiler itself
4308          * to function, or provide metadata that's needed if other events (e.g.
4309          * allocations, exceptions) are dynamically enabled/disabled.
4310          */
4311
4312         mono_profiler_set_runtime_shutdown_begin_callback (handle, log_early_shutdown);
4313         mono_profiler_set_runtime_shutdown_end_callback (handle, log_shutdown);
4314         mono_profiler_set_runtime_initialized_callback (handle, runtime_initialized);
4315
4316         mono_profiler_set_gc_event_callback (handle, gc_event);
4317
4318         mono_profiler_set_thread_started_callback (handle, thread_start);
4319         mono_profiler_set_thread_stopped_callback (handle, thread_end);
4320         mono_profiler_set_thread_name_callback (handle, thread_name);
4321
4322         mono_profiler_set_domain_loaded_callback (handle, domain_loaded);
4323         mono_profiler_set_domain_unloading_callback (handle, domain_unloaded);
4324         mono_profiler_set_domain_name_callback (handle, domain_name);
4325
4326         mono_profiler_set_context_loaded_callback (handle, context_loaded);
4327         mono_profiler_set_context_unloaded_callback (handle, context_unloaded);
4328
4329         mono_profiler_set_assembly_loaded_callback (handle, assembly_loaded);
4330         mono_profiler_set_assembly_unloading_callback (handle, assembly_unloaded);
4331
4332         mono_profiler_set_image_loaded_callback (handle, image_loaded);
4333         mono_profiler_set_image_unloading_callback (handle, image_unloaded);
4334
4335         mono_profiler_set_class_loaded_callback (handle, class_loaded);
4336
4337         mono_profiler_set_jit_done_callback (handle, method_jitted);
4338
4339         if (ENABLED (PROFLOG_EXCEPTION_EVENTS)) {
4340                 mono_profiler_set_exception_throw_callback (handle, throw_exc);
4341                 mono_profiler_set_exception_clause_callback (handle, clause_exc);
4342         }
4343
4344         if (ENABLED (PROFLOG_MONITOR_EVENTS)) {
4345                 mono_profiler_set_monitor_contention_callback (handle, monitor_contention);
4346                 mono_profiler_set_monitor_acquired_callback (handle, monitor_acquired);
4347                 mono_profiler_set_monitor_failed_callback (handle, monitor_failed);
4348         }
4349
4350         if (ENABLED (PROFLOG_GC_EVENTS))
4351                 mono_profiler_set_gc_resize_callback (handle, gc_resize);
4352
4353         if (ENABLED (PROFLOG_GC_ALLOCATION_EVENTS)) {
4354                 mono_profiler_enable_allocations ();
4355                 mono_profiler_set_gc_allocation_callback (handle, gc_alloc);
4356         }
4357
4358         if (ENABLED (PROFLOG_GC_MOVE_EVENTS))
4359                 mono_profiler_set_gc_moves_callback (handle, gc_moves);
4360
4361         if (ENABLED (PROFLOG_GC_ROOT_EVENTS))
4362                 mono_profiler_set_gc_roots_callback (handle, gc_roots);
4363
4364         if (ENABLED (PROFLOG_GC_HANDLE_EVENTS)) {
4365                 mono_profiler_set_gc_handle_created_callback (handle, gc_handle_created);
4366                 mono_profiler_set_gc_handle_deleted_callback (handle, gc_handle_deleted);
4367         }
4368
4369         if (ENABLED (PROFLOG_FINALIZATION_EVENTS)) {
4370                 mono_profiler_set_gc_finalizing_callback (handle, finalize_begin);
4371                 mono_profiler_set_gc_finalized_callback (handle, finalize_end);
4372                 mono_profiler_set_gc_finalizing_object_callback (handle, finalize_object_begin);
4373                 mono_profiler_set_gc_finalized_object_callback (handle, finalize_object_end);
4374         } else if (log_config.hs_mode == MONO_PROFILER_HEAPSHOT_ON_DEMAND) {
4375                 //On Demand heapshot uses the finalizer thread to force a collection and thus a heapshot
4376                 mono_profiler_set_gc_finalized_callback (handle, finalize_end);
4377         }
4378
4379         if (ENABLED (PROFLOG_SAMPLE_EVENTS))
4380                 mono_profiler_set_sample_hit_callback (handle, mono_sample_hit);
4381
4382         if (ENABLED (PROFLOG_JIT_EVENTS))
4383                 mono_profiler_set_jit_code_buffer_callback (handle, code_buffer_new);
4384
4385         if (log_config.enter_leave) {
4386                 mono_profiler_set_call_instrumentation_filter_callback (handle, method_filter);
4387                 mono_profiler_set_method_enter_callback (handle, method_enter);
4388                 mono_profiler_set_method_leave_callback (handle, method_leave);
4389                 mono_profiler_set_method_exception_leave_callback (handle, method_exc_leave);
4390         }
4391
4392         if (log_config.collect_coverage)
4393                 mono_profiler_set_coverage_filter_callback (handle, coverage_filter);
4394
4395         mono_profiler_enable_sampling (handle);
4396
4397         /*
4398          * If no sample option was given by the user, this just leaves the sampling
4399          * thread in idle mode. We do this even if no option was given so that we
4400          * can warn if another profiler controls sampling parameters.
4401          */
4402         if (!mono_profiler_set_sample_mode (handle, log_config.sampling_mode, log_config.sample_freq))
4403                 mono_profiler_printf_err ("Another profiler controls sampling parameters; the log profiler will not be able to modify them.");
4404 }