Tue Mar 16 11:20:14 CET 2010 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / profiler / mono-profiler-logging.c
index 44d0f8b131cfb95188daefb26ff2188a0ae327d9..9ed3cb8cde298fd011036322b3b09cf45922b004 100644 (file)
@@ -9,6 +9,7 @@
 #include <config.h>
 #include <mono/metadata/profiler.h>
 #include <mono/metadata/class.h>
+#include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/loader.h>
@@ -133,7 +134,7 @@ typedef enum {
 
 static gboolean use_fast_timer = FALSE;
 
-#if (defined(__i386__) || defined(__x86_64__)) && ! defined(PLATFORM_WIN32)
+#if (defined(__i386__) || defined(__x86_64__)) && ! defined(HOST_WIN32)
 
 #if defined(__i386__)
 static const guchar cpuid_impl [] = {
@@ -451,8 +452,6 @@ typedef struct _ProfilerPerThreadData {
        struct _ProfilerPerThreadData* next;
 } ProfilerPerThreadData;
 
-#define MAX_STATISTICAL_CALL_CHAIN_DEPTH 128
-
 typedef struct _ProfilerStatisticalHit {
        gpointer *address;
        MonoDomain *domain;
@@ -676,7 +675,7 @@ typedef struct _ProfilerExecutableFiles {
 #define CLEANUP_WRITER_THREAD() do {profiler->writer_thread_terminated = TRUE;} while (0)
 #define CHECK_WRITER_THREAD() (! profiler->writer_thread_terminated)
 
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
@@ -840,7 +839,7 @@ static __thread ProfilerPerThreadData * tls_profiler_per_thread_data;
 #define PROFILER_FILE_WRITE_BUFFER_SIZE (profiler->write_buffer_size)
 typedef struct _ProfilerFileWriteBuffer {
        struct _ProfilerFileWriteBuffer *next;
-       guint8 buffer [];
+       guint8 buffer [MONO_ZERO_LEN_ARRAY];
 } ProfilerFileWriteBuffer;
 
 #define CHECK_PROFILER_ENABLED() do {\
@@ -878,6 +877,7 @@ struct _MonoProfiler {
        ProfilerStatisticalData *statistical_data_ready;
        ProfilerStatisticalData *statistical_data_second_buffer;
        int statistical_call_chain_depth;
+       MonoProfilerCallChainStrategy statistical_call_chain_strategy;
        
        ProfilerCodeChunks code_chunks;
        
@@ -4463,7 +4463,7 @@ method_free (MonoProfiler *profiler, MonoMethod *method) {
 }
 
 static void
-thread_start (MonoProfiler *profiler, gsize tid) {
+thread_start (MonoProfiler *profiler, intptr_t tid) {
        ProfilerPerThreadData *data;
        ProfilerEventData *event;
        GET_PROFILER_THREAD_DATA (data);
@@ -4472,7 +4472,7 @@ thread_start (MonoProfiler *profiler, gsize tid) {
        COMMIT_RESERVED_EVENTS (data);
 }
 static void
-thread_end (MonoProfiler *profiler, gsize tid) {
+thread_end (MonoProfiler *profiler, intptr_t tid) {
        ProfilerPerThreadData *data;
        ProfilerEventData *event;
        GET_PROFILER_THREAD_DATA (data);
@@ -5315,6 +5315,10 @@ profiler_shutdown (MonoProfiler *prof)
        
        LOG_WRITER_THREAD ("profiler_shutdown: zeroing relevant flags");
        mono_profiler_set_events (0);
+       /* During shutdown searching for MonoJitInfo is not possible... */
+       if (profiler->statistical_call_chain_strategy == MONO_PROFILER_CALL_CHAIN_MANAGED) {
+               mono_profiler_install_statistical_call_chain (NULL, 0, MONO_PROFILER_CALL_CHAIN_NONE);
+       }
        //profiler->flags = 0;
        //profiler->action_flags.unreachable_objects = FALSE;
        //profiler->action_flags.heap_shot = FALSE;
@@ -5413,6 +5417,7 @@ setup_user_options (const char *arguments) {
        profiler->per_thread_buffer_size = 10000;
        profiler->statistical_buffer_size = 10000;
        profiler->statistical_call_chain_depth = 0;
+       profiler->statistical_call_chain_strategy = MONO_PROFILER_CALL_CHAIN_NATIVE;
        profiler->write_buffer_size = 1024;
        profiler->dump_next_heap_snapshots = 0;
        profiler->heap_shot_was_requested = FALSE;
@@ -5468,12 +5473,25 @@ setup_user_options (const char *arguments) {
                                int value = atoi (equals + 1);
                                FAIL_IF_HAS_MINUS;
                                if (value > 0) {
-                                       if (value > MAX_STATISTICAL_CALL_CHAIN_DEPTH) {
-                                               value = MAX_STATISTICAL_CALL_CHAIN_DEPTH;
+                                       if (value > MONO_PROFILER_MAX_STAT_CALL_CHAIN_DEPTH) {
+                                               value = MONO_PROFILER_MAX_STAT_CALL_CHAIN_DEPTH;
                                        }
                                        profiler->statistical_call_chain_depth = value;
                                        profiler->flags |= MONO_PROFILE_STATISTICAL;
                                }
+                       } else if (! (strncmp (argument, "call-chain-strategy", equals_position) && strncmp (argument, "ccs", equals_position))) {
+                               char *parameter = equals + 1;
+                               FAIL_IF_HAS_MINUS;
+                               if (! strcmp (parameter, "native")) {
+                                       profiler->statistical_call_chain_strategy = MONO_PROFILER_CALL_CHAIN_NATIVE;
+                               } else if (! strcmp (parameter, "glibc")) {
+                                       profiler->statistical_call_chain_strategy = MONO_PROFILER_CALL_CHAIN_GLIBC;
+                               } else if (! strcmp (parameter, "managed")) {
+                                       profiler->statistical_call_chain_strategy = MONO_PROFILER_CALL_CHAIN_MANAGED;
+                               } else {
+                                       failure_message = "invalid call chain strategy in argument %s";
+                                       goto failure_handling;
+                               }
                        } else if (! (strncmp (argument, "statistical-thread-buffer-size", equals_position) && strncmp (argument, "sbs", equals_position))) {
                                int value = atoi (equals + 1);
                                FAIL_IF_HAS_MINUS;
@@ -5847,7 +5865,7 @@ mono_profiler_startup (const char *desc)
        mono_profiler_install_allocation (object_allocated);
        mono_profiler_install_monitor (monitor_event);
        mono_profiler_install_statistical (statistical_hit);
-       mono_profiler_install_statistical_call_chain (statistical_call_chain, profiler->statistical_call_chain_depth);
+       mono_profiler_install_statistical_call_chain (statistical_call_chain, profiler->statistical_call_chain_depth, profiler->statistical_call_chain_strategy);
        mono_profiler_install_gc (gc_event, gc_resize);
        mono_profiler_install_runtime_initialized (runtime_initialized);
 #if (HAS_OPROFILE)