+
+/*
+ * The following code is here to maintain compatibility with a few profiler API
+ * functions used by Xamarin.{Android,iOS,Mac} so that they keep working
+ * regardless of which system Mono version is used.
+ *
+ * TODO: Remove this some day if we're OK with breaking compatibility.
+ */
+
+typedef void *MonoLegacyProfiler;
+
+typedef void (*MonoLegacyProfileFunc) (MonoLegacyProfiler *prof);
+typedef void (*MonoLegacyProfileThreadFunc) (MonoLegacyProfiler *prof, uintptr_t tid);
+typedef void (*MonoLegacyProfileGCFunc) (MonoLegacyProfiler *prof, MonoProfilerGCEvent event, int generation);
+typedef void (*MonoLegacyProfileGCResizeFunc) (MonoLegacyProfiler *prof, int64_t new_size);
+typedef void (*MonoLegacyProfileJitResult) (MonoLegacyProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
+
+struct _MonoProfiler {
+ MonoProfilerHandle handle;
+ MonoLegacyProfiler *profiler;
+ MonoLegacyProfileFunc shutdown_callback;
+ MonoLegacyProfileThreadFunc thread_start, thread_end;
+ MonoLegacyProfileGCFunc gc_event;
+ MonoLegacyProfileGCResizeFunc gc_heap_resize;
+ MonoLegacyProfileJitResult jit_end2;
+};
+
+static MonoProfiler *current;
+
+MONO_API void mono_profiler_install (MonoLegacyProfiler *prof, MonoLegacyProfileFunc callback);
+MONO_API void mono_profiler_install_thread (MonoLegacyProfileThreadFunc start, MonoLegacyProfileThreadFunc end);
+MONO_API void mono_profiler_install_gc (MonoLegacyProfileGCFunc callback, MonoLegacyProfileGCResizeFunc heap_resize_callback);
+MONO_API void mono_profiler_install_jit_end (MonoLegacyProfileJitResult end);
+MONO_API void mono_profiler_set_events (int flags);
+
+static void
+shutdown_cb (MonoProfiler *prof)
+{
+ prof->shutdown_callback (prof->profiler);
+}
+
+void
+mono_profiler_install (MonoLegacyProfiler *prof, MonoLegacyProfileFunc callback)
+{
+ current = g_new0 (MonoProfiler, 1);
+ current->handle = mono_profiler_create (current);
+ current->profiler = prof;
+ current->shutdown_callback = callback;
+
+ if (callback)
+ mono_profiler_set_runtime_shutdown_end_callback (current->handle, shutdown_cb);
+}
+
+static void
+thread_start_cb (MonoProfiler *prof, uintptr_t tid)
+{
+ prof->thread_start (prof->profiler, tid);
+}
+
+static void
+thread_stop_cb (MonoProfiler *prof, uintptr_t tid)
+{
+ prof->thread_end (prof->profiler, tid);
+}
+
+void
+mono_profiler_install_thread (MonoLegacyProfileThreadFunc start, MonoLegacyProfileThreadFunc end)
+{
+ current->thread_start = start;
+ current->thread_end = end;
+
+ if (start)
+ mono_profiler_set_thread_started_callback (current->handle, thread_start_cb);
+
+ if (end)
+ mono_profiler_set_thread_stopped_callback (current->handle, thread_stop_cb);
+}
+
+static void
+gc_event_cb (MonoProfiler *prof, MonoProfilerGCEvent event, uint32_t generation)
+{
+ prof->gc_event (prof->profiler, event, generation);
+}
+
+static void
+gc_resize_cb (MonoProfiler *prof, uintptr_t size)
+{
+ prof->gc_heap_resize (prof->profiler, size);
+}
+
+void
+mono_profiler_install_gc (MonoLegacyProfileGCFunc callback, MonoLegacyProfileGCResizeFunc heap_resize_callback)
+{
+ current->gc_event = callback;
+ current->gc_heap_resize = heap_resize_callback;
+
+ if (callback)
+ mono_profiler_set_gc_event_callback (current->handle, gc_event_cb);
+
+ if (heap_resize_callback)
+ mono_profiler_set_gc_resize_callback (current->handle, gc_resize_cb);
+}
+
+static void
+jit_done_cb (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo)
+{
+ prof->jit_end2 (prof->profiler, method, jinfo, 0);
+}
+
+static void
+jit_failed_cb (MonoProfiler *prof, MonoMethod *method)
+{
+ prof->jit_end2 (prof->profiler, method, NULL, 1);
+}
+
+void
+mono_profiler_install_jit_end (MonoLegacyProfileJitResult end)
+{
+ current->jit_end2 = end;
+
+ if (end) {
+ mono_profiler_set_jit_done_callback (current->handle, jit_done_cb);
+ mono_profiler_set_jit_failed_callback (current->handle, jit_failed_cb);
+ }
+}
+
+void
+mono_profiler_set_events (int flags)
+{
+ /* Do nothing. */
+}