2 * mono.c: Main driver for the Mono JIT engine
5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
13 #include "mono/metadata/debug-helpers.h"
14 #include "mono/metadata/verify.h"
15 #include "mono/metadata/profiler.h"
16 #include "mono/metadata/threadpool.h"
17 #include "mono/metadata/mono-config.h"
18 #include <mono/metadata/profiler-private.h>
19 #include <mono/os/util.h>
23 * @image: reference to an image
24 * @verbose: If true, print debugging information on stdout.
26 * JIT compilation of all methods in the image.
29 mono_jit_compile_image (MonoImage *image, int verbose)
32 MonoTableInfo *t = &image->tables [MONO_TABLE_METHOD];
35 for (i = 0; i < t->rows; i++) {
37 method = mono_get_method (image,
38 (MONO_TABLE_METHOD << 24) | (i + 1),
42 g_print ("Compiling: %s:%s\n\n", image->assembly_name, method->name);
44 if (method->flags & METHOD_ATTRIBUTE_ABSTRACT) {
46 printf ("ABSTARCT\n");
48 mono_compile_method (method);
55 find_class_in_assembly (MonoAssembly *assembly, const char *namespace, const char *name)
60 class = mono_class_from_name (assembly->image, namespace, name);
64 for (ptr = assembly->image->references; ptr && *ptr; ptr++) {
65 class = find_class_in_assembly (*ptr, namespace, name);
74 find_method_in_assembly (MonoAssembly *assembly, MonoMethodDesc *mdesc)
79 method = mono_method_desc_search_in_image (mdesc, assembly->image);
83 for (ptr = assembly->image->references; ptr && *ptr; ptr++) {
84 method = find_method_in_assembly (*ptr, mdesc);
93 * mono_jit_compile_class:
94 * @assembly: Lookup things in this assembly
95 * @compile_class: Name of the image/class/method to compile
96 * @compile_times: Compile it that many times
97 * @verbose: If true, print debugging information on stdout.
99 * JIT compilation of the image/class/method.
101 * @compile_class can be one of:
103 * - an image name (`@corlib')
104 * - a class name (`System.Int32')
105 * - a method name (`System.Int32:Parse')
108 mono_jit_compile_class (MonoAssembly *assembly, char *compile_class,
109 int compile_times, int verbose)
111 const char *cmethod = strrchr (compile_class, ':');
116 MonoDomain *domain = mono_domain_get ();
118 if (compile_class [0] == '@') {
119 MonoImage *image = mono_image_loaded (compile_class + 1);
121 g_error ("Cannot find image %s", compile_class + 1);
123 g_print ("Compiling image %s\n", image->name);
124 for (j = 0; j < compile_times; ++j)
125 mono_jit_compile_image (image, verbose);
126 } else if (cmethod) {
127 MonoMethodDesc *mdesc;
129 mdesc = mono_method_desc_new (compile_class, FALSE);
131 g_error ("Invalid method name '%s'", compile_class);
132 m = find_method_in_assembly (assembly, mdesc);
134 g_error ("Cannot find method '%s'", compile_class);
135 for (j = 0; j < compile_times; ++j) {
136 code = mono_compile_method (m);
138 g_hash_table_remove (domain->jit_code_hash, m);
141 cname = strrchr (compile_class, '.');
145 cname = compile_class;
146 compile_class = (char *)"";
148 class = find_class_in_assembly (assembly, compile_class, cname);
150 g_error ("Cannot find class %s.%s", compile_class, cname);
151 mono_class_init (class);
152 for (j = 0; j < compile_times; ++j) {
153 for (i = 0; i < class->method.count; ++i) {
154 if (class->methods [i]->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
156 if (class->methods [i]->flags & METHOD_ATTRIBUTE_ABSTRACT)
159 g_print ("Compiling: %s.%s:%s\n",
160 compile_class, cname, class->methods [i]->name);
161 code = mono_compile_method (class->methods [i]);
162 g_hash_table_remove (domain->jit_code_hash, class->methods [i]);
173 "mono %s, the Mono ECMA CLI JIT Compiler, (C) 2001, 2002 Ximian, Inc.\n\n"
174 "Usage is: %s [options] executable args...\n\n", VERSION, name);
176 "Runtime Debugging:\n"
177 " -d debug the jit, show disassembler output.\n"
178 " --dump-asm dumps the assembly code generated\n"
179 " --dump-forest dumps the reconstructed forest\n"
180 " --print-vtable print the VTable of all used classes\n"
181 " --stats print statistics about the jit operations\n"
182 " --trace printf function call trace\n"
183 " --compile NAME compile NAME, then exit.\n"
184 " NAME is in one of the following formats:\n"
185 " namespace.name compile the given class\n"
186 " namespace.name:method compile the given method\n"
187 " @imagename compile the given image\n"
188 " --ncompile NUM compile methods NUM times (default: 1000)\n"
191 " --debug[=FORMAT] write a debugging file. FORMAT is one of:\n"
192 " stabs to write stabs information\n"
193 " dwarf to write dwarf2 information\n"
194 " dwarf-plus to write extended dwarf2 information\n"
195 " --debug-args ARGS comma-separated list of additional arguments for the\n"
196 " symbol writer. See the manpage for details.\n"
197 " --profile record and dump profile info\n"
198 " --breakonex set a breakpoint for unhandled exception\n"
199 " --break NAME insert a breakpoint at the start of method NAME\n"
200 " (NAME is in `namespace.name:methodname' format)\n"
201 " --precompile name precompile NAME before executing the main application:\n"
202 " NAME is in one of the following formats:\n"
203 " namespace.name compile the given class\n"
204 " namespace.name:method compile the given method\n"
205 " @imagename compile the given image\n"
208 " --config filename Load specified config file instead of the default.\n"
209 " --fast-iconv Use fast floating point integer conversion\n"
210 " --noinline Disable code inliner\n"
211 " --nointrinsic Disable memcopy inliner\n"
212 " --nols disable linear scan register allocation\n"
213 " --share-code force jit to produce shared code\n"
214 " --workers n maximum number of worker threads\n"
220 main (int argc, char *argv [])
223 MonoAssembly *assembly;
225 int compile_times = 1000;
226 char *compile_class = NULL;
227 char *debug_args = NULL;
228 char *file, *error, *config_file = NULL;
229 gboolean testjit = FALSE;
231 GList *precompile_classes = NULL;
233 g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
234 g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
239 for (i = 1; i < argc && argv [i][0] == '-'; i++){
240 if (strcmp (argv [i], "--help") == 0) {
242 } else if (strcmp (argv [i], "-d") == 0) {
244 mono_jit_dump_asm = TRUE;
245 mono_jit_dump_forest = TRUE;
246 } else if (strcmp (argv [i], "--dump-asm") == 0)
247 mono_jit_dump_asm = TRUE;
248 else if (strcmp (argv [i], "--dump-forest") == 0)
249 mono_jit_dump_forest = TRUE;
250 else if (strcmp (argv [i], "--trace") == 0)
251 mono_jit_trace_calls = TRUE;
252 else if (strcmp (argv [i], "--share-code") == 0)
253 mono_jit_share_code = TRUE;
254 else if (strcmp (argv [i], "--noinline") == 0)
255 mono_jit_inline_code = FALSE;
256 else if (strcmp (argv [i], "--nointrinsic") == 0)
257 mono_inline_memcpy = FALSE;
258 else if (strcmp (argv [i], "--nols") == 0)
259 mono_use_linear_scan = FALSE;
260 else if (strcmp (argv [i], "--breakonex") == 0)
261 mono_break_on_exc = TRUE;
262 else if (strcmp (argv [i], "--print-vtable") == 0)
263 mono_print_vtable = TRUE;
264 else if (strcmp (argv [i], "--break") == 0) {
265 MonoMethodDesc *desc = mono_method_desc_new (argv [++i], FALSE);
267 g_error ("Invalid method name '%s'", argv [i]);
268 mono_debug_methods = g_list_append (mono_debug_methods, desc);
269 } else if (strcmp (argv [i], "--count") == 0) {
270 compile_times = atoi (argv [++i]);
271 } else if (strcmp (argv [i], "--config") == 0) {
272 config_file = argv [++i];
273 } else if (strcmp (argv [i], "--workers") == 0) {
274 mono_worker_threads = atoi (argv [++i]);
275 if (mono_worker_threads < 1)
276 mono_worker_threads = 1;
277 } else if (strcmp (argv [i], "--profile") == 0) {
278 mono_jit_profile = TRUE;
279 mono_profiler_install_simple ();
280 } else if (strcmp (argv [i], "--compile") == 0) {
281 compile_class = argv [++i];
282 } else if (strcmp (argv [i], "--ncompile") == 0) {
283 compile_times = atoi (argv [++i]);
284 } else if (strcmp (argv [i], "--stats") == 0) {
285 memset (&mono_jit_stats, 0, sizeof (MonoJitStats));
286 mono_jit_stats.enabled = TRUE;
287 } else if (strncmp (argv [i], "--debug=", 8) == 0) {
288 const char *format = &argv [i][8];
290 if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
291 g_error ("You can only use one debugging format.");
292 if (strcmp (format, "stabs") == 0)
293 mono_debug_format = MONO_DEBUG_FORMAT_STABS;
294 else if (strcmp (format, "dwarf") == 0)
295 mono_debug_format = MONO_DEBUG_FORMAT_DWARF2;
296 else if (strcmp (format, "dwarf-plus") == 0)
297 mono_debug_format = MONO_DEBUG_FORMAT_DWARF2_PLUS;
299 g_error ("Unknown debugging format: %s", argv [i] + 8);
300 } else if (strcmp (argv [i], "--debug") == 0) {
301 if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
302 g_error ("You can only use one debugging format.");
303 mono_debug_format = MONO_DEBUG_FORMAT_DWARF2_PLUS;
304 } else if (strcmp (argv [i], "--debug-args") == 0) {
306 g_error ("You can use --debug-args only once.");
307 debug_args = argv [++i];
308 } else if (strcmp (argv [i], "--precompile") == 0) {
309 precompile_classes = g_list_append (precompile_classes, argv [++i]);
310 } else if (strcmp (argv [i], "--verbose") == 0) {
312 } else if (strcmp (argv [i], "--fast-iconv") == 0) {
313 mono_use_fast_iconv = TRUE;
323 mono_config_parse (config_file);
324 mono_set_rootdir (argv [0]);
325 domain = mono_jit_init (file);
327 error = mono_verify_corlib ();
329 fprintf (stderr, "Corlib not in sync with this runtime: %s\n", error);
333 assembly = mono_domain_assembly_open (domain, file);
335 fprintf (stderr, "Can not open image %s\n", file);
339 if (mono_debug_format != MONO_DEBUG_FORMAT_NONE) {
340 MonoDebugHandle *debug;
343 args = g_strsplit (debug_args ? debug_args : "", ",", -1);
344 debug = mono_debug_open (assembly, mono_debug_format, (const char **) args);
345 mono_debug_add_image (debug, assembly->image);
350 mono_jit_compile_image (assembly->image, TRUE);
351 } else if (compile_class) {
352 mono_jit_compile_class (assembly, compile_class, compile_times, TRUE);
356 for (tmp = precompile_classes; tmp; tmp = tmp->next)
357 mono_jit_compile_class (assembly, tmp->data, 1, verbose);
359 retval = mono_jit_exec (domain, assembly, argc - i, argv + i);
360 printf ("RESULT: %d\n", retval);
363 mono_profiler_shutdown ();
364 mono_jit_cleanup (domain);