2 * mono-profiler-aot.c: Ahead of Time Compiler Profiler for Mono.
5 * Copyright 2008-2009 Novell, Inc (http://www.novell.com)
7 * This profiler collects profiling information usable by the Mono AOT compiler
8 * to generate better code. It saves the information into files under ~/.mono.
9 * The AOT compiler can load these files during compilation.
10 * Currently, only the order in which methods were compiled is saved,
11 * allowing more efficient function ordering in the AOT files.
12 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
16 #include <mono/metadata/profiler.h>
17 #include <mono/metadata/tokentype.h>
18 #include <mono/metadata/tabledefs.h>
19 #include <mono/metadata/debug-helpers.h>
20 #include <mono/metadata/assembly.h>
31 struct _MonoProfiler
{
39 typedef struct ForeachData
{
47 foreach_method (gpointer data
, gpointer user_data
)
49 ForeachData
*udata
= (ForeachData
*)user_data
;
50 MonoMethod
*method
= (MonoMethod
*)data
;
53 if (!mono_method_get_token (method
) || mono_class_get_image (mono_method_get_class (method
)) != udata
->image
)
56 name
= mono_method_full_name (method
, TRUE
);
57 fprintf (udata
->outfile
, "%s\n", name
);
62 output_image (gpointer key
, gpointer value
, gpointer user_data
)
64 MonoImage
*image
= (MonoImage
*)key
;
65 PerImageData
*image_data
= (PerImageData
*)value
;
66 MonoProfiler
*prof
= (MonoProfiler
*)user_data
;
67 char *tmp
, *outfile_name
;
72 tmp
= g_strdup_printf ("%s/.mono/aot-profile-data", g_get_home_dir ());
74 if (!g_file_test (tmp
, G_FILE_TEST_IS_DIR
)) {
78 err
= mkdir (tmp
, 0777);
81 fprintf (stderr
, "mono-profiler-aot: Unable to create output directory '%s': %s\n", tmp
, g_strerror (errno
));
88 outfile_name
= g_strdup_printf ("%s/%s-%d", tmp
, mono_image_get_name (image
), i
);
90 if (!g_file_test (outfile_name
, G_FILE_TEST_IS_REGULAR
))
96 printf ("Creating output file: %s\n", outfile_name
);
98 outfile
= fopen (outfile_name
, "w+");
101 fprintf (outfile
, "#VER:%d\n", 2);
104 data
.outfile
= outfile
;
107 g_list_foreach (image_data
->methods
, foreach_method
, &data
);
110 /* called at the end of the program */
112 prof_shutdown (MonoProfiler
*prof
)
114 g_hash_table_foreach (prof
->images
, output_image
, prof
);
118 prof_jit_enter (MonoProfiler
*prof
, MonoMethod
*method
)
123 prof_jit_leave (MonoProfiler
*prof
, MonoMethod
*method
, int result
)
125 MonoImage
*image
= mono_class_get_image (mono_method_get_class (method
));
128 data
= (PerImageData
*)g_hash_table_lookup (prof
->images
, image
);
130 data
= g_new0 (PerImageData
, 1);
131 g_hash_table_insert (prof
->images
, image
, data
);
134 data
->methods
= g_list_append (data
->methods
, method
);
138 mono_profiler_startup (const char *desc
);
140 /* the entry point */
142 mono_profiler_startup (const char *desc
)
146 prof
= g_new0 (MonoProfiler
, 1);
147 prof
->images
= g_hash_table_new (NULL
, NULL
);
149 mono_profiler_install (prof
, prof_shutdown
);
151 mono_profiler_install_jit_compile (prof_jit_enter
, prof_jit_leave
);
153 mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION
);