/* * Licensed to the .NET Foundation under one or more agreements. * The .NET Foundation licenses this file to you under the MIT license. * See the LICENSE file in the project root for more information. */ #ifndef __MONO_PROFILER_PRIVATE_H__ #define __MONO_PROFILER_PRIVATE_H__ #include #define MONO_PROFILER_UNSTABLE_GC_ROOTS #include #include #include #include struct _MonoProfilerDesc { MonoProfilerHandle next; MonoProfiler *prof; volatile gpointer cleanup_callback; volatile gpointer coverage_filter; volatile gpointer call_instrumentation_filter; #define _MONO_PROFILER_EVENT(name) \ volatile gpointer name ## _cb; #define MONO_PROFILER_EVENT_0(name, type) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \ _MONO_PROFILER_EVENT(name) #include #undef MONO_PROFILER_EVENT_0 #undef MONO_PROFILER_EVENT_1 #undef MONO_PROFILER_EVENT_2 #undef MONO_PROFILER_EVENT_3 #undef MONO_PROFILER_EVENT_4 #undef _MONO_PROFILER_EVENT }; typedef struct { gboolean startup_done; MonoProfilerHandle profilers; gboolean code_coverage; mono_mutex_t coverage_mutex; GHashTable *coverage_hash; MonoProfilerHandle sampling_owner; MonoSemType sampling_semaphore; MonoProfilerSampleMode sample_mode; guint32 sample_freq; gboolean allocations; gboolean call_contexts; void (*context_enable) (void); gpointer (*context_get_this) (MonoProfilerCallContext *); gpointer (*context_get_argument) (MonoProfilerCallContext *, guint32); gpointer (*context_get_local) (MonoProfilerCallContext *, guint32); gpointer (*context_get_result) (MonoProfilerCallContext *); void (*context_free_buffer) (gpointer); #define _MONO_PROFILER_EVENT(name) \ volatile gint32 name ## _count; #define MONO_PROFILER_EVENT_0(name, type) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \ _MONO_PROFILER_EVENT(name) #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \ _MONO_PROFILER_EVENT(name) #include #undef MONO_PROFILER_EVENT_0 #undef MONO_PROFILER_EVENT_1 #undef MONO_PROFILER_EVENT_2 #undef MONO_PROFILER_EVENT_3 #undef MONO_PROFILER_EVENT_4 #undef _MONO_PROFILER_EVENT } MonoProfilerState; extern MonoProfilerState mono_profiler_state; typedef struct { guint32 entries; struct { guchar *cil_code; guint32 count; } data [1]; } MonoProfilerCoverageInfo; void mono_profiler_started (void); void mono_profiler_cleanup (void); static inline gboolean mono_profiler_installed (void) { return !!mono_profiler_state.profilers; } MonoProfilerCoverageInfo *mono_profiler_coverage_alloc (MonoMethod *method, guint32 entries); struct _MonoProfilerCallContext { /* * Must be the first field (the JIT relies on it). Only filled out if this * is a JIT frame; otherwise, zeroed. */ MonoContext context; /* * A non-NULL MonoInterpFrameHandle if this is an interpreter frame. */ gpointer interp_frame; MonoMethod *method; /* * Points to the return value for an epilogue context. For a prologue, this * is set to NULL. */ gpointer return_value; }; MonoProfilerCallInstrumentationFlags mono_profiler_get_call_instrumentation_flags (MonoMethod *method); gboolean mono_profiler_sampling_enabled (void); void mono_profiler_sampling_thread_post (void); void mono_profiler_sampling_thread_wait (void); static inline gboolean mono_profiler_allocations_enabled (void) { return mono_profiler_state.allocations; } #define _MONO_PROFILER_EVENT(name, ...) \ ICALL_DECL_EXPORT void mono_profiler_raise_ ## name (__VA_ARGS__); #define MONO_PROFILER_EVENT_0(name, type) \ _MONO_PROFILER_EVENT(name, void) #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \ _MONO_PROFILER_EVENT(name, arg1_type arg1_name) #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \ _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name) #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \ _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name) #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \ _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name) #include #undef MONO_PROFILER_EVENT_0 #undef MONO_PROFILER_EVENT_1 #undef MONO_PROFILER_EVENT_2 #undef MONO_PROFILER_EVENT_3 #undef MONO_PROFILER_EVENT_4 #undef _MONO_PROFILER_EVENT // These are the macros the rest of the runtime should use. #define MONO_PROFILER_ENABLED(name) \ G_UNLIKELY (mono_profiler_state.name ## _count) #define MONO_PROFILER_RAISE(name, args) \ do { \ if (MONO_PROFILER_ENABLED (name)) \ mono_profiler_raise_ ## name args; \ } while (0) #endif // __MONO_PROFILER_PRIVATE_H__