/*
|
* 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 <mono/metadata/class-internals.h>
|
#include <mono/metadata/profiler.h>
|
#include <mono/utils/mono-context.h>
|
#include <mono/utils/mono-os-mutex.h>
|
#include <mono/utils/mono-os-semaphore.h>
|
|
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)
|
#define MONO_PROFILER_EVENT_5(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name, arg5_type, arg5_name) \
|
_MONO_PROFILER_EVENT(name)
|
#include <mono/metadata/profiler-events.h>
|
#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_5
|
#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 fileio;
|
|
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)
|
#define MONO_PROFILER_EVENT_5(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name, arg5_type, arg5_name) \
|
_MONO_PROFILER_EVENT(name)
|
#include <mono/metadata/profiler-events.h>
|
#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_5
|
#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)
|
#define MONO_PROFILER_EVENT_5(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name, arg5_type, arg5_name) \
|
_MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name, arg5_type arg5_name)
|
#include <mono/metadata/profiler-events.h>
|
#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_5
|
#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__
|