2002-05-21 Martin Baulig <martin@gnome.org>
[mono.git] / mono / jit / mono.c
1 /*
2  * mono.c: Main driver for the Mono JIT engine
3  *
4  * Author:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *
7  * (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
8  */
9 #include "jit.h"
10 #include "regset.h"
11 #include "codegen.h"
12 #include "debug.h"
13 #include "mono/metadata/debug-helpers.h"
14 #include "mono/metadata/verify.h"
15 #include "mono/metadata/profiler.h"
16 #include <mono/os/util.h>
17
18 /**
19  * mono_jit_assembly:
20  * @assembly: reference to an assembly
21  *
22  * JIT compilation of all methods in the assembly. Prints debugging
23  * information on stdout.
24  */
25 static void
26 mono_jit_assembly (MonoAssembly *assembly)
27 {
28         MonoImage *image = assembly->image;
29         MonoMethod *method;
30         MonoTableInfo *t = &image->tables [MONO_TABLE_METHOD];
31         int i;
32
33         for (i = 0; i < t->rows; i++) {
34
35                 method = mono_get_method (image, 
36                                           (MONO_TABLE_METHOD << 24) | (i + 1), 
37                                           NULL);
38
39                 printf ("\nMethod: %s\n\n", method->name);
40
41                 if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
42                         printf ("ABSTARCT\n");
43                 else
44                         arch_compile_method (method);
45
46         }
47
48 }
49
50 static void
51 usage (char *name)
52 {
53         fprintf (stderr,
54                  "%s %s, the Mono ECMA CLI JIT Compiler, (C) 2001, 2002 Ximian, Inc.\n\n"
55                  "Usage is: %s [options] executable args...\n\n", name,  VERSION, name);
56         fprintf (stderr,
57                  "Runtime Debugging:\n"
58                  "    -d               debug the jit, show disassembler output.\n"
59                  "    --dump-asm       dumps the assembly code generated\n"
60                  "    --dump-forest    dumps the reconstructed forest\n"
61                  "    --print-vtable   print the VTable of all used classes\n"
62                  "    --stats          print statistics about the jit operations\n"
63                  "    --trace          printf function call trace\n"
64                  "    --compile cname  compile methods in given class\n"
65                  "                     format: (namespace.name[:methodname])\n"
66                  "    --ncompile num   compile methods num times (default: 1000)\n"
67                  "\n"
68                  "Development:"
69                  "    --dwarf          write dwarf2 debug information\n"
70                  "    --dwarf-plus     write extended dwarf2 debug information\n"
71                  "    --profile        record and dump profile info\n"
72                  "    --stabs          write stabs debug information\n"
73                  "    --debug name     insert a breakpoint at the start of method name\n"
74                  "\n"
75                  "Runtime:"
76                  "    --fast-iconv     Use fast floating point integer conversion\n"
77                  "    --noinline       Disable code inliner\n"
78                  "    --nols           disable linear scan register allocation\n"
79                  "    --share-code     force jit to produce shared code\n"
80                  "    --workers n      maximum number of worker threads\n"
81                 );
82         exit (1);
83 }
84
85 int 
86 main (int argc, char *argv [])
87 {
88         MonoDomain *domain;
89         MonoAssembly *assembly;
90         int retval = 0, i;
91         int compile_times = 1000;
92         char *compile_class = NULL;
93         char *file, *error;
94         gboolean testjit = FALSE;
95         int stack, verbose = FALSE;
96
97         g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
98         g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
99         
100         if (argc < 2)
101                 usage (argv [0]);
102
103         for (i = 1; i < argc && argv [i][0] == '-'; i++){
104                 if (strcmp (argv [i], "--help") == 0) {
105                         usage (argv [0]);
106                 } else if (strcmp (argv [i], "-d") == 0) {
107                         testjit = TRUE;
108                         mono_jit_dump_asm = TRUE;
109                         mono_jit_dump_forest = TRUE;
110                 } else if (strcmp (argv [i], "--dump-asm") == 0)
111                         mono_jit_dump_asm = TRUE;
112                 else if (strcmp (argv [i], "--dump-forest") == 0)
113                         mono_jit_dump_forest = TRUE;
114                 else if (strcmp (argv [i], "--trace") == 0)
115                         mono_jit_trace_calls = TRUE;
116                 else if (strcmp (argv [i], "--share-code") == 0)
117                         mono_jit_share_code = TRUE;
118                 else if (strcmp (argv [i], "--noinline") == 0)
119                         mono_jit_inline_code = FALSE;
120                 else if (strcmp (argv [i], "--nols") == 0)
121                         mono_use_linear_scan = FALSE;
122                 else if (strcmp (argv [i], "--print-vtable") == 0)
123                         mono_print_vtable = TRUE;
124                 else if (strcmp (argv [i], "--debug") == 0) {
125                         MonoMethodDesc *desc = mono_method_desc_new (argv [++i], FALSE);
126                         if (!desc)
127                                 g_error ("Invalid method name '%s'", argv [i]);
128                         mono_debug_methods = g_list_append (mono_debug_methods, desc);
129                 } else if (strcmp (argv [i], "--count") == 0) {
130                         compile_times = atoi (argv [++i]);
131                 } else if (strcmp (argv [i], "--workers") == 0) {
132                         mono_worker_threads = atoi (argv [++i]);
133                         if (mono_worker_threads < 1)
134                                 mono_worker_threads = 1;
135                 } else if (strcmp (argv [i], "--profile") == 0) {
136                         mono_jit_profile = TRUE;
137                         mono_profiler_install_simple ();
138                 } else if (strcmp (argv [i], "--compile") == 0) {
139                         compile_class = argv [++i];
140                 } else if (strcmp (argv [i], "--ncompile") == 0) {
141                         compile_times = atoi (argv [++i]);
142                 } else if (strcmp (argv [i], "--stats") == 0) {
143                         memset (&mono_jit_stats, 0, sizeof (MonoJitStats));
144                         mono_jit_stats.enabled = TRUE;
145                 } else if (strcmp (argv [i], "--stabs") == 0) {
146                         if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
147                                 g_error ("You can only use one debugging format.");
148                         mono_debug_format = MONO_DEBUG_FORMAT_STABS;
149                 } else if (strcmp (argv [i], "--dwarf") == 0) {
150                         if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
151                                 g_error ("You can only use one debugging format.");
152                         mono_debug_format = MONO_DEBUG_FORMAT_DWARF2;
153                 } else if (strcmp (argv [i], "--dwarf-plus") == 0) {
154                         if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
155                                 g_error ("You can only use one debugging format.");
156                         mono_debug_format = MONO_DEBUG_FORMAT_DWARF2_PLUS;
157                 } else if (strcmp (argv [i], "--verbose") == 0) {
158                         verbose = TRUE;;
159                 } else if (strcmp (argv [i], "--fast-iconv") == 0) {
160                         mono_use_fast_iconv = TRUE;
161                 } else
162                         usage (argv [0]);
163         }
164         
165         file = argv [i];
166
167         if (!file)
168                 usage (argv [0]);
169
170         mono_set_rootdir (argv [0]);
171         domain = mono_jit_init (file);
172
173         error = mono_verify_corlib ();
174         if (error) {
175                 fprintf (stderr, "Corlib not in sync with this runtime: %s\n", error);
176                 exit (1);
177         }
178
179         assembly = mono_domain_assembly_open (domain, file);
180         if (!assembly){
181                 fprintf (stderr, "Can not open image %s\n", file);
182                 exit (1);
183         }
184
185         if (mono_debug_format != MONO_DEBUG_FORMAT_NONE) {
186                 MonoDebugHandle *handle = mono_debug_open_file (file, mono_debug_format);
187                 mono_debug_add_image (handle, assembly->image);
188         }
189
190         if (testjit) {
191                 mono_jit_assembly (assembly);
192         } else if (compile_class) {
193                 const char *cmethod = strrchr (compile_class, ':');
194                 char *cname;
195                 char *code;
196                 int j;
197                 MonoClass *class;
198
199                 if (cmethod) {
200                         MonoMethodDesc *mdesc;
201                         MonoMethod *m;
202                         mdesc = mono_method_desc_new (compile_class, FALSE);
203                         if (!mdesc)
204                                 g_error ("Invalid method name '%s'", compile_class);
205                         m = mono_method_desc_search_in_image (mdesc, assembly->image);
206                         if (!m)
207                                 g_error ("Cannot find method '%s'", compile_class);
208                         for (j = 0; j < compile_times; ++j) {
209                                 code = arch_compile_method (m);
210                                 g_free (code);
211                         }
212                 } else {
213                         cname = strrchr (compile_class, '.');
214                         if (cname)
215                                 *cname++ = 0;
216                         else {
217                                 cname = compile_class;
218                                 compile_class = (char *)"";
219                         }
220                         class = mono_class_from_name (assembly->image, compile_class, cname);
221                         if (!class)
222                                 g_error ("Cannot find class %s.%s", compile_class, cname);
223                         mono_class_init (class);
224                         for (j = 0; j < compile_times; ++j) {
225                                 for (i = 0; i < class->method.count; ++i) {
226                                         if (class->methods [i]->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
227                                                 continue;
228                                         if (class->methods [i]->flags & METHOD_ATTRIBUTE_ABSTRACT)
229                                                 continue;
230                                         if (verbose)
231                                                 g_print ("Compiling: %s\n", class->methods [i]->name);
232                                         code = arch_compile_method (class->methods [i]);
233                                         g_free (code);
234                                 }
235                         }
236                 }
237         } else {
238                 retval = mono_jit_exec (domain, assembly, argc - i, argv + i);
239                 printf ("RESULT: %d\n", retval);
240         }
241
242         mono_profiler_shutdown ();
243         mono_jit_cleanup (domain);
244
245         return retval;
246 }
247
248