+/*
+ * 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>
+#define MONO_PROFILER_UNSTABLE_GC_ROOTS
#include <mono/metadata/profiler.h>
-#include "mono/utils/mono-compiler.h"
-#include <glib.h>
-
-extern MonoProfileFlags mono_profiler_events;
-
-enum {
- MONO_PROFILE_START_LOAD,
- MONO_PROFILE_END_LOAD,
- MONO_PROFILE_START_UNLOAD,
- MONO_PROFILE_END_UNLOAD
+#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)
+#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
};
typedef struct {
- int entries;
- struct {
- guchar* cil_code;
- int count;
- } data [1];
-} MonoProfileCoverageInfo;
-
-void mono_profiler_shutdown (void) MONO_INTERNAL;
-
-void mono_profiler_method_enter (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_method_leave (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_method_jit (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_method_end_jit (MonoMethod *method, MonoJitInfo* jinfo, int result) MONO_INTERNAL;
-void mono_profiler_method_free (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_method_start_invoke (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_method_end_invoke (MonoMethod *method) MONO_INTERNAL;
-
-void mono_profiler_code_transition (MonoMethod *method, int result) MONO_INTERNAL;
-void mono_profiler_allocation (MonoObject *obj, MonoClass *klass) MONO_INTERNAL;
-void mono_profiler_monitor_event (MonoObject *obj, MonoProfilerMonitorEvent event) MONO_INTERNAL;
-void mono_profiler_stat_hit (guchar *ip, void *context) MONO_INTERNAL;
-void mono_profiler_stat_call_chain (int call_chain_depth, guchar **ips, void *context) MONO_INTERNAL;
-int mono_profiler_stat_get_call_chain_depth (void) MONO_INTERNAL;
-MonoProfilerCallChainStrategy mono_profiler_stat_get_call_chain_strategy (void) MONO_INTERNAL;
-void mono_profiler_thread_start (gsize tid) MONO_INTERNAL;
-void mono_profiler_thread_end (gsize tid) MONO_INTERNAL;
-void mono_profiler_thread_name (gsize tid, const char *name) MONO_INTERNAL;
-
-void mono_profiler_exception_thrown (MonoObject *exception) MONO_INTERNAL;
-void mono_profiler_exception_method_leave (MonoMethod *method) MONO_INTERNAL;
-void mono_profiler_exception_clause_handler (MonoMethod *method, int clause_type, int clause_num) MONO_INTERNAL;
-
-void mono_profiler_assembly_event (MonoAssembly *assembly, int code) MONO_INTERNAL;
-void mono_profiler_assembly_loaded (MonoAssembly *assembly, int result) MONO_INTERNAL;
-
-void mono_profiler_module_event (MonoImage *image, int code) MONO_INTERNAL;
-void mono_profiler_module_loaded (MonoImage *image, int result) MONO_INTERNAL;
-
-void mono_profiler_class_event (MonoClass *klass, int code) MONO_INTERNAL;
-void mono_profiler_class_loaded (MonoClass *klass, int result) MONO_INTERNAL;
+ 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 <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
+} MonoProfilerState;
+
+extern MonoProfilerState mono_profiler_state;
-void mono_profiler_appdomain_event (MonoDomain *domain, int code) MONO_INTERNAL;
-void mono_profiler_appdomain_loaded (MonoDomain *domain, int result) MONO_INTERNAL;
-
-void mono_profiler_iomap (char *report, const char *pathname, const char *new_pathname) MONO_INTERNAL;
-
-MonoProfileCoverageInfo* mono_profiler_coverage_alloc (MonoMethod *method, int entries) MONO_INTERNAL;
-void mono_profiler_coverage_free (MonoMethod *method) MONO_INTERNAL;
-
-void mono_profiler_gc_event (MonoGCEvent e, int generation) MONO_INTERNAL;
-void mono_profiler_gc_heap_resize (gint64 new_size) MONO_INTERNAL;
-void mono_profiler_gc_moves (void **objects, int num) MONO_INTERNAL;
-void mono_profiler_gc_handle (int op, int type, uintptr_t handle, MonoObject *obj) MONO_INTERNAL;
-void mono_profiler_gc_roots (int num, void **objects, int *root_types, uintptr_t *extra_info) MONO_INTERNAL;
-
-void mono_profiler_code_chunk_new (gpointer chunk, int size) MONO_INTERNAL;
-void mono_profiler_code_chunk_destroy (gpointer chunk) MONO_INTERNAL;
-void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, void *data) MONO_INTERNAL;
-
-void mono_profiler_runtime_initialized (void) MONO_INTERNAL;
-
-int64_t mono_profiler_get_sampling_rate (void) MONO_INTERNAL;
-MonoProfileSamplingMode mono_profiler_get_sampling_mode (void) MONO_INTERNAL;
-
-#endif /* __MONO_PROFILER_PRIVATE_H__ */
+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 <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
+
+// 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__