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