e44f2573ab1c7b754a2a1f8f7e48e077a2b21b1b
[cacao.git] / main.c
1 /* main.c **********************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Contains main() and variables for the global options.
8         This module does the following tasks:
9            - Command line option handling
10            - Calling initialization routines
11            - Calling the class loader
12            - Running the main method
13
14         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
15         Changes: Andi Krall          EMAIL: cacao@complang.tuwien.ac.at
16                  Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
17                          Philipp Tomsich     EMAIL: cacao@complang.tuwien.ac.at
18
19         Last Change: $Id: main.c 491 2003-10-20 17:56:03Z twisti $
20
21 *******************************************************************************/
22
23 #include "global.h"
24
25 #include "tables.h"
26 #include "loader.h"
27 #include "jit.h"
28
29 #include "asmpart.h"
30 #include "builtin.h"
31 #include "native.h"
32
33 #include "threads/thread.h"
34
35 bool compileall = false;
36 bool verbose =  false;
37
38 static bool showmethods = false;
39 static bool showconstantpool = false;
40 static bool showutf = false;
41 static classinfo *topclass;
42
43 #ifndef USE_THREADS
44 void **stackbottom = 0;
45 #endif
46
47
48 /* internal function: get_opt *************************************************
49         
50         decodes the next command line option
51         
52 ******************************************************************************/
53
54 #define OPT_DONE       -1
55 #define OPT_ERROR       0
56 #define OPT_IGNORE      1
57
58 #define OPT_CLASSPATH   2
59 #define OPT_D           3
60 #define OPT_MS          4
61 #define OPT_MX          5
62 #define OPT_VERBOSE1    6
63 #define OPT_VERBOSE     7
64 #define OPT_VERBOSEGC   8
65 #define OPT_VERBOSECALL 9
66 #define OPT_IEEE        10
67 #define OPT_SOFTNULL    11
68 #define OPT_TIME        12
69 #define OPT_STAT        13
70 #define OPT_LOG         14
71 #define OPT_CHECK       15
72 #define OPT_LOAD        16
73 #define OPT_METHOD      17
74 #define OPT_SIGNATURE   18
75 #define OPT_SHOW        19
76 #define OPT_ALL         20
77 #define OPT_OLOOP       24
78 #define OPT_INLINING    25
79 #define OPT_RT          26
80 #define OPT_XTA         27 
81 #define OPT_VTA         28 
82
83
84 struct {char *name; bool arg; int value;} opts[] = {
85         {"classpath",   true,   OPT_CLASSPATH},
86         {"D",           true,   OPT_D},
87         {"ms",          true,   OPT_MS},
88         {"mx",          true,   OPT_MX},
89         {"noasyncgc",   false,  OPT_IGNORE},
90         {"noverify",    false,  OPT_IGNORE},
91         {"oss",         true,   OPT_IGNORE},
92         {"ss",          true,   OPT_IGNORE},
93         {"v",           false,  OPT_VERBOSE1},
94         {"verbose",     false,  OPT_VERBOSE},
95         {"verbosegc",   false,  OPT_VERBOSEGC},
96         {"verbosecall", false,  OPT_VERBOSECALL},
97         {"ieee",        false,  OPT_IEEE},
98         {"softnull",    false,  OPT_SOFTNULL},
99         {"time",        false,  OPT_TIME},
100         {"stat",        false,  OPT_STAT},
101         {"log",         true,   OPT_LOG},
102         {"c",           true,   OPT_CHECK},
103         {"l",           false,  OPT_LOAD},
104         {"m",           true,   OPT_METHOD},
105         {"sig",         true,   OPT_SIGNATURE},
106         {"s",           true,   OPT_SHOW},
107         {"all",         false,  OPT_ALL},
108         {"oloop",       false,  OPT_OLOOP},
109         {"i",               true,   OPT_INLINING},
110         {"rt",          false,  OPT_RT},
111         {"xta",         false,  OPT_XTA},
112         {"vta",         false,  OPT_VTA},
113         {NULL,  false, 0}
114 };
115
116 static int opt_ind = 1;
117 static char *opt_arg;
118
119 static int get_opt (int argc, char **argv) 
120 {
121         char *a;
122         int i;
123         
124         if (opt_ind >= argc) return OPT_DONE;
125         
126         a = argv[opt_ind];
127         if (a[0] != '-') return OPT_DONE;
128
129         for (i=0; opts[i].name; i++) {
130                 if (! opts[i].arg) {
131                         if (strcmp(a+1, opts[i].name) == 0) {  /* boolean option found */
132                                 opt_ind++;
133                                 return opts[i].value;
134                         }
135                 }
136                 else {
137                         if (strcmp(a+1, opts[i].name) == 0) { /* parameter option found */
138                                 opt_ind++;
139                                 if (opt_ind < argc) {
140                                         opt_arg = argv[opt_ind];
141                                         opt_ind++;
142                                         return opts[i].value;
143                                 }
144                                 return OPT_ERROR;
145                         }
146                         else {
147                                 size_t l = strlen(opts[i].name);
148                                 if (strlen(a+1) > l) {
149                                         if (memcmp (a+1, opts[i].name, l)==0) {
150                                                 opt_ind++;
151                                                 opt_arg = a+1+l;
152                                                 return opts[i].value;
153                                         }
154                                 }
155                         }
156                 }
157         } /* end for */ 
158
159         return OPT_ERROR;
160 }
161
162
163
164
165 /******************** interne Function: print_usage ************************
166
167 Prints the correct usage syntax to stdout.
168
169 ***************************************************************************/
170
171 static void print_usage()
172 {
173         printf ("USAGE: cacao [options] classname [program arguments]\n");
174         printf ("Options:\n");
175         printf ("          -classpath path ...... specify a path to look for classes\n");
176         printf ("          -Dpropertyname=value . add an entry to the property list\n");
177         printf ("          -mx maxmem[k|m] ...... specify the size for the heap\n");
178         printf ("          -ms initmem[k|m] ..... specify the initial size for the heap\n");
179         printf ("          -v ................... write state-information\n");
180         printf ("          -verbose ............. write more information\n");
181         printf ("          -verbosegc ........... write message for each GC\n");
182         printf ("          -verbosecall ......... write message for each call\n");
183         printf ("          -ieee ................ use ieee compliant arithmetic\n");
184         printf ("          -softnull ............ use software nullpointer check\n");
185         printf ("          -time ................ measure the runtime\n");
186         printf ("          -stat ................ detailed compiler statistics\n");
187         printf ("          -log logfile ......... specify a name for the logfile\n");
188         printf ("          -c(heck)b(ounds) ..... don't check array bounds\n");
189         printf ("                  s(ync) ....... don't check for synchronization\n");
190         printf ("          -oloop ............... optimize array accesses in loops\n"); 
191         printf ("          -l ................... don't start the class after loading\n");
192         printf ("          -all ................. compile all methods, no execution\n");
193         printf ("          -m ................... compile only a specific method\n");
194         printf ("          -sig ................. specify signature for a specific method\n");
195         printf ("          -s(how)a(ssembler) ... show disassembled listing\n");
196         printf ("                 c(onstants) ... show the constant pool\n");
197         printf ("                 d(atasegment).. show data segment listing\n");
198         printf ("                 i(ntermediate). show intermediate representation\n");
199         printf ("                 m(ethods)...... show class fields and methods\n");
200         printf ("                 u(tf) ......... show the utf - hash\n");
201         printf ("          -i     n ............. activate inlining\n");
202         printf ("                 v ............. inline virtual methods\n");
203         printf ("                 e ............. inline methods with exceptions\n");
204         printf ("                 p ............. optimize argument renaming\n");
205         printf ("                 o ............. inline methods of foreign classes\n");
206         printf ("          -rt .................. use rapid type analysis\n");
207         printf ("          -xta ................. use x type analysis\n");
208         printf ("          -vta ................. use variable type analysis\n");
209 }   
210
211
212
213 /***************************** Function: print_times *********************
214
215         Prints a summary of CPU time usage.
216
217 **************************************************************************/
218
219 static void print_times()
220 {
221         long int totaltime = getcputime();
222         long int runtime = totaltime - loadingtime - compilingtime;
223
224         sprintf (logtext, "Time for loading classes: %ld secs, %ld millis",
225              loadingtime / 1000000, (loadingtime % 1000000) / 1000);
226         dolog();
227         sprintf (logtext, "Time for compiling code:  %ld secs, %ld millis",
228              compilingtime / 1000000, (compilingtime % 1000000) / 1000);
229         dolog();
230         sprintf (logtext, "Time for running program: %ld secs, %ld millis",
231              runtime / 1000000, (runtime % 1000000) / 1000);
232         dolog();
233         sprintf (logtext, "Total time: %ld secs, %ld millis",
234              totaltime / 1000000, (totaltime % 1000000) / 1000);
235         dolog();
236 }
237
238
239
240
241
242
243 /***************************** Function: print_stats *********************
244
245         outputs detailed compiler statistics
246
247 **************************************************************************/
248
249 static void print_stats()
250 {
251         sprintf (logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
252         dolog();
253         sprintf (logtext, "Number of compiled Methods: %d", count_methods);
254         dolog();
255         sprintf (logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
256         dolog();
257         sprintf (logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
258         dolog();
259         sprintf (logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
260         dolog();
261         sprintf (logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
262         dolog();
263         sprintf (logtext, "Size of compiled JavaVM-Instructions:   %d(%d)", count_javacodesize,
264                                                       count_javacodesize - count_methods * 18);
265         dolog();
266         sprintf (logtext, "Size of compiled Exception Tables:      %d", count_javaexcsize);
267         dolog();
268         sprintf (logtext, "Value of extended instruction set var:  %d", has_ext_instr_set);
269         dolog();
270         sprintf (logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
271         dolog();
272         sprintf (logtext, "Number of Spills: %d", count_spills);
273         dolog();
274         sprintf (logtext, "Number of Activ    Pseudocommands: %5d", count_pcmd_activ);
275         dolog();
276         sprintf (logtext, "Number of Drop     Pseudocommands: %5d", count_pcmd_drop);
277         dolog();
278         sprintf (logtext, "Number of Const    Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
279         dolog();
280         sprintf (logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
281         dolog();
282         sprintf (logtext, "Number of Move     Pseudocommands: %5d", count_pcmd_move);
283         dolog();
284         sprintf (logtext, "Number of Load     Pseudocommands: %5d", count_load_instruction);
285         dolog();
286         sprintf (logtext, "Number of Store    Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
287         dolog();
288         sprintf (logtext, "Number of OP       Pseudocommands: %5d", count_pcmd_op);
289         dolog();
290         sprintf (logtext, "Number of DUP      Pseudocommands: %5d", count_dup_instruction);
291         dolog();
292         sprintf (logtext, "Number of Mem      Pseudocommands: %5d", count_pcmd_mem);
293         dolog();
294         sprintf (logtext, "Number of Method   Pseudocommands: %5d", count_pcmd_met);
295         dolog();
296         sprintf (logtext, "Number of Branch   Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
297                           count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
298         dolog();
299         sprintf (logtext, "Number of Table    Pseudocommands: %5d", count_pcmd_table);
300         dolog();
301         sprintf (logtext, "Number of Useful   Pseudocommands: %5d", count_pcmd_table +
302                  count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
303         dolog();
304         sprintf (logtext, "Number of Null Pointer Checks:     %5d", count_check_null);
305         dolog();
306         sprintf (logtext, "Number of Array Bound Checks:      %5d", count_check_bound);
307         dolog();
308         sprintf (logtext, "Number of Try-Blocks: %d", count_tryblocks);
309         dolog();
310         sprintf (logtext, "Maximal count of stack elements:   %d", count_max_new_stack);
311         dolog();
312         sprintf (logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
313         dolog();
314         sprintf (logtext, "Distribution of stack sizes at block boundary");
315         dolog();
316         sprintf (logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
317         dolog();
318         sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
319                 count_block_stack[1],count_block_stack[2],count_block_stack[3],count_block_stack[4],
320                 count_block_stack[5],count_block_stack[6],count_block_stack[7],count_block_stack[8],
321                 count_block_stack[9],count_block_stack[10]);
322         dolog();
323         sprintf (logtext, "Distribution of store stack depth");
324         dolog();
325         sprintf (logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
326         dolog();
327         sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
328                 count_store_depth[1],count_store_depth[2],count_store_depth[3],count_store_depth[4],
329                 count_store_depth[5],count_store_depth[6],count_store_depth[7],count_store_depth[8],
330                 count_store_depth[9],count_store_depth[10]);
331         dolog();
332         sprintf (logtext, "Distribution of store creator chains first part");
333         dolog();
334         sprintf (logtext, "    0    1    2    3    4    5    6    7    8    9  ");
335         dolog();
336         sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
337                 count_store_length[1],count_store_length[2],count_store_length[3],count_store_length[4],
338                 count_store_length[5],count_store_length[6],count_store_length[7],count_store_length[8],
339                 count_store_length[9]);
340         dolog();
341         sprintf (logtext, "Distribution of store creator chains second part");
342         dolog();
343         sprintf (logtext, "   10   11   12   13   14   15   16   17   18   19  >=20");
344         dolog();
345         sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
346                 count_store_length[11],count_store_length[12],count_store_length[13],count_store_length[14],
347                 count_store_length[15],count_store_length[16],count_store_length[17],count_store_length[18],
348                 count_store_length[19],count_store_length[20]);
349         dolog();
350         sprintf (logtext, "Distribution of analysis iterations");
351         dolog();
352         sprintf (logtext, "    1    2    3    4    >=5");
353         dolog();
354         sprintf (logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0],count_analyse_iterations[1],
355                 count_analyse_iterations[2],count_analyse_iterations[3],count_analyse_iterations[4]);
356         dolog();
357         sprintf (logtext, "Distribution of basic blocks per method");
358         dolog();
359         sprintf (logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75  >75");
360         dolog();
361         sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
362                 count_method_bb_distribution[1],count_method_bb_distribution[2],count_method_bb_distribution[3],
363                 count_method_bb_distribution[4],count_method_bb_distribution[5],count_method_bb_distribution[6],
364                 count_method_bb_distribution[7],count_method_bb_distribution[8]);
365         dolog();
366         sprintf (logtext, "Distribution of basic block sizes");
367         dolog();
368         sprintf (logtext,
369         "  0    1    2    3    4   5   6   7   8   9 <13 <15 <17 <19 <21 <26 <31 >30");
370         dolog();
371         sprintf (logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
372                 count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
373                 count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
374                 count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
375                 count_block_size_distribution[9], count_block_size_distribution[10],count_block_size_distribution[11],
376                 count_block_size_distribution[12],count_block_size_distribution[13],count_block_size_distribution[14],
377                 count_block_size_distribution[15],count_block_size_distribution[16],count_block_size_distribution[17]);
378         dolog();
379         sprintf (logtext, "Size of Code Area (Kb):  %10.3f", (float) count_code_len / 1024);
380         dolog();
381         sprintf (logtext, "Size of data Area (Kb):  %10.3f", (float) count_data_len / 1024);
382         dolog();
383         sprintf (logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
384         dolog();
385         sprintf (logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
386         dolog();
387         sprintf (logtext, "Size of Vftbl (Kb):      %10.3f", (float) count_vftbl_len / 1024);
388         dolog();
389         sprintf (logtext, "Size of comp stub (Kb):  %10.3f", (float) count_cstub_len / 1024);
390         dolog();
391         sprintf (logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
392         dolog();
393         sprintf (logtext, "Size of Utf (Kb):        %10.3f", (float) count_utf_len / 1024);
394         dolog();
395         sprintf (logtext, "Size of VMCode (Kb):     %10.3f(%d)", (float) count_vmcode_len / 1024,
396                                                       count_vmcode_len - 18 * count_all_methods);
397         dolog();
398         sprintf (logtext, "Size of ExTable (Kb):    %10.3f", (float) count_extable_len / 1024);
399         dolog();
400         sprintf (logtext, "Number of class loads:   %d", count_class_loads);
401         dolog();
402         sprintf (logtext, "Number of class inits:   %d", count_class_inits);
403         dolog();
404         sprintf (logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
405         dolog();
406
407         sprintf (logtext, "Calls of utf_new: %22d", count_utf_new);
408         dolog();
409         sprintf (logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
410         dolog();
411 }
412
413
414 /********** Function: class_compile_methods   (debugging only) ********/
415
416 void class_compile_methods ()
417 {
418         int        i;
419         classinfo  *c;
420         methodinfo *m;
421         
422         c = list_first (&linkedclasses);
423         while (c) {
424                 for (i = 0; i < c -> methodscount; i++) {
425                         m = &(c->methods[i]);
426                         if (m->jcode) {
427                                 (void) jit_compile(m);
428                                 }
429                         }
430                 c = list_next (&linkedclasses, c);
431                 }
432 }
433
434 /*
435  * void exit_handler(void)
436  * -----------------------
437  * The exit_handler function is called upon program termination to shutdown
438  * the various subsystems and release the resources allocated to the VM.
439  */
440
441 void exit_handler(void)
442 {
443         /********************* Print debug tables ************************/
444                                 
445         if (showmethods) class_showmethods (topclass);
446         if (showconstantpool)  class_showconstantpool (topclass);
447         if (showutf)           utf_show ();
448
449 #ifdef USE_THREADS
450         clear_thread_flags();           /* restores standard file descriptor
451                                                                    flags */
452 #endif
453
454         /************************ Free all resources *******************/
455
456         heap_close ();                          /* must be called before compiler_close and
457                                                                    loader_close because finalization occurs
458                                                                    here */
459
460         loader_close ();
461         tables_close ( literalstring_free );
462
463         if (verbose || getcompilingtime || statistics) {
464                 log_text ("CACAO terminated");
465                 if (statistics)
466                         print_stats ();
467                 if (getcompilingtime)
468                         print_times ();
469                 mem_usagelog(1);
470         }
471 }
472
473 /************************** Function: main *******************************
474
475    The main program.
476    
477 **************************************************************************/
478
479 int main(int argc, char **argv)
480 {
481         s4 i,j;
482         char *cp;
483         java_objectheader *local_exceptionptr = 0;
484         void *dummy;
485         
486         /********** interne (nur fuer main relevante Optionen) **************/
487    
488         char logfilename[200] = "";
489         u4 heapsize = 64000000;
490         u4 heapstartsize = 200000;
491         char classpath[500] = ".:/usr/local/lib/java/classes";
492         bool startit = true;
493         char *specificmethodname = NULL;
494         char *specificsignature = NULL;
495
496 #ifndef USE_THREADS
497         stackbottom = &dummy;
498 #endif
499         
500         if (0 != atexit(exit_handler))
501                 panic("unable to register exit_handler");
502
503         /************ Collect info from the environment ************************/
504
505         cp = getenv ("CLASSPATH");
506         if (cp) {
507                 strcpy (classpath, cp);
508         }
509
510         /***************** Interpret the command line *****************/
511    
512         checknull = false;
513         checkfloats = false;
514
515         while ( (i = get_opt(argc,argv)) != OPT_DONE) {
516
517                 switch (i) {
518                 case OPT_IGNORE: break;
519                         
520                 case OPT_CLASSPATH:    
521                         strcpy (classpath + strlen(classpath), ":");
522                         strcpy (classpath + strlen(classpath), opt_arg);
523                         break;
524                                 
525                 case OPT_D:
526                         {
527                                 int n,l=strlen(opt_arg);
528                                 for (n=0; n<l; n++) {
529                                         if (opt_arg[n]=='=') {
530                                                 opt_arg[n] = '\0';
531                                                 attach_property (opt_arg, opt_arg+n+1);
532                                                 goto didit;
533                                         }
534                                 }
535                                 print_usage();
536                                 exit(10);
537                                         
538                         didit: ;
539                         }       
540                 break;
541                                 
542                 case OPT_MS:
543                 case OPT_MX:
544                         if (opt_arg[strlen(opt_arg)-1] == 'k') {
545                                 j = 1024 * atoi(opt_arg);
546                         }
547                         else if (opt_arg[strlen(opt_arg)-1] == 'm') {
548                                 j = 1024 * 1024 * atoi(opt_arg);
549                         }
550                         else j = atoi(opt_arg);
551                                 
552                         if (i==OPT_MX) heapsize = j;
553                         else heapstartsize = j;
554                         break;
555
556                 case OPT_VERBOSE1:
557                         verbose = true;
558                         break;
559                                                                 
560                 case OPT_VERBOSE:
561                         verbose = true;
562                         loadverbose = true;
563                         initverbose = true;
564                         compileverbose = true;
565                         break;
566                                 
567                 case OPT_VERBOSEGC:
568                         collectverbose = true;
569                         break;
570                                 
571                 case OPT_VERBOSECALL:
572                         runverbose = true;
573                         break;
574                                 
575                 case OPT_IEEE:
576                         checkfloats = true;
577                         break;
578
579                 case OPT_SOFTNULL:
580                         checknull = true;
581                         break;
582
583                 case OPT_TIME:
584                         getcompilingtime = true;
585                         getloadingtime = true;
586                         break;
587                                         
588                 case OPT_STAT:
589                         statistics = true;
590                         break;
591                                         
592                 case OPT_LOG:
593                         strcpy (logfilename, opt_arg);
594                         break;
595                         
596                 case OPT_CHECK:
597                         for (j=0; j<strlen(opt_arg); j++) {
598                                 switch (opt_arg[j]) {
599                                 case 'b': checkbounds=false; break;
600                                 case 's': checksync=false; break;
601                                 default:  print_usage();
602                                         exit(10);
603                                 }
604                         }
605                         break;
606                         
607                 case OPT_LOAD:
608                         startit = false;
609                         makeinitializations = false;
610                         break;
611
612                 case OPT_METHOD:
613                         startit = false;
614                         specificmethodname = opt_arg;                   
615                         makeinitializations = false;
616                         break;
617                         
618                 case OPT_SIGNATURE:
619                         specificsignature = opt_arg;                    
620                         break;
621                         
622                 case OPT_ALL:
623                         compileall = true;              
624                         startit = false;
625                         makeinitializations = false;
626                         break;
627                         
628                 case OPT_SHOW:       /* Display options */
629                         for (j=0; j<strlen(opt_arg); j++) {             
630                                 switch (opt_arg[j]) {
631                                 case 'a':  showdisassemble=true; compileverbose=true; break;
632                                 case 'c':  showconstantpool=true; break;
633                                 case 'd':  showddatasegment=true; break;
634                                 case 'i':  showintermediate=true; compileverbose=true; break;
635                                 case 'm':  showmethods=true; break;
636                                 case 'u':  showutf=true; break;
637                                 default:   print_usage();
638                                         exit(10);
639                                 }
640                         }
641                         break;
642                         
643                 case OPT_OLOOP:
644                         opt_loops = true;
645                         break;
646
647                 case OPT_INLINING:
648                         for (j=0; j<strlen(opt_arg); j++) {             
649                                 switch (opt_arg[j]) {
650                                 case 'n':  useinlining = true; break;
651                                 case 'v':  inlinevirtuals = true; break;
652                                 case 'e':  inlineexceptions = true; break;
653                                 case 'p':  inlineparamopt = true; break;
654                                 case 'o':  inlineoutsiders = true; break;
655                                 default:   print_usage();
656                                         exit(10);
657                                 }
658                         }
659                         break;
660
661                 case OPT_RT:
662                         opt_rt = true;
663                         break;
664
665                 case OPT_XTA:
666                         /***opt_xta = true; not yet **/
667                         break;
668
669                 case OPT_VTA:
670                         /***opt_vta = true; not yet **/
671                         break;
672
673                 default:
674                         print_usage();
675                         exit(10);
676                 }
677         }
678    
679    
680         if (opt_ind >= argc) {
681                 print_usage ();
682                 exit(10);
683         }
684
685
686         /**************************** Program start *****************************/
687
688         log_init (logfilename);
689         if (verbose) {
690                 log_text (
691                                   "CACAO started -------------------------------------------------------");
692         }
693         
694         suck_init (classpath);
695         native_setclasspath (classpath);
696                 
697         tables_init();
698         heap_init(heapsize, heapstartsize, &dummy);
699         jit_init();
700         loader_init();
701
702         native_loadclasses ();
703
704
705         /*********************** Load JAVA classes  ***************************/
706    
707         cp = argv[opt_ind++];
708         for (i=strlen(cp)-1; i>=0; i--) {     /* Transform dots into slashes */
709                 if (cp[i]=='.') cp[i]='/';        /* in the class name */
710         }
711
712         topclass = loader_load ( utf_new_char (cp) );
713
714         if (exceptionptr != 0)
715         {
716                 printf ("#### Class loader has thrown: ");
717                 utf_display (exceptionptr->vftbl->class->name);
718                 printf ("\n");
719
720                 exceptionptr = 0;
721         }
722
723         if (topclass == 0)
724         {
725                 printf("#### Could not find top class - exiting\n");
726                 exit(1);
727         }
728
729         gc_init();
730
731 #ifdef USE_THREADS
732         initThreads((u1*)&dummy);                   /* schani */
733 #endif
734
735         /************************* Start worker routines ********************/
736
737         if (startit) {
738                 methodinfo *mainmethod;
739                 java_objectarray *a; 
740
741                 heap_addreference((void**) &a);
742
743                 mainmethod = class_findmethod (
744                                                                            topclass,
745                                                                            utf_new_char ("main"), 
746                                                                            utf_new_char ("([Ljava/lang/String;)V")
747                                                                            );
748                 if (!mainmethod) panic ("Can not find method 'void main(String[])'");
749                 if ((mainmethod->flags & ACC_STATIC) != ACC_STATIC) panic ("main is not static!");
750                         
751                 a = builtin_anewarray (argc - opt_ind, class_java_lang_String);
752                 for (i=opt_ind; i<argc; i++) {
753                         a->data[i-opt_ind] = javastring_new (utf_new_char (argv[i]) );
754                 }
755                 local_exceptionptr = asm_calljavamethod (mainmethod, a, NULL, NULL, NULL );
756         
757                 if (local_exceptionptr) {
758                         printf ("#### Program has thrown: ");
759                         utf_display (local_exceptionptr->vftbl->class->name);
760                         printf ("\n");
761                 }
762                                         /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
763                                         /*RTAprint*/    printCallgraph (); }
764
765                                         /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
766                                         /*RTprint*/     printf("Last RTA Info -");
767                                         /*RTprint*/     printRThierarchyInfo(mainmethod); 
768                                         /*RTprint*/     }
769                                         /*RTprint*/     printObjectClassHeirarchy1( );
770
771
772 #ifdef USE_THREADS
773                 killThread(currentThread);
774 #endif
775                 fprintf(stderr, "still here\n");
776         }
777
778         /************* If requested, compile all methods ********************/
779
780         if (compileall) {
781                 class_compile_methods();
782         }
783
784
785         /******** If requested, compile a specific method ***************/
786
787         if (specificmethodname) {
788                 methodinfo *m;
789                 if (specificsignature)
790                         m = class_findmethod(topclass, 
791                                                                  utf_new_char(specificmethodname),
792                                                                  utf_new_char(specificsignature));
793                 else
794                         m = class_findmethod(topclass, 
795                                                                  utf_new_char(specificmethodname), NULL);
796                 if (!m) panic ("Specific method not found");
797                         (void) jit_compile(m);
798         }
799
800         exit(0);
801 }
802
803
804
805 /************************************ Shutdown function *********************************
806
807         Terminates the system immediately without freeing memory explicitly (to be
808         used only for abnormal termination)
809         
810 *****************************************************************************************/
811
812 void cacao_shutdown(s4 status)
813 {
814                                         /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
815                                         /*RTAprint*/    printCallgraph (NULL); }
816
817                                         /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
818                                         /*RTprint*/     printf("RTA Information -");
819                                         /*RTprint*/     printRThierarchyInfo(NULL); }
820
821         if (verbose || getcompilingtime || statistics) {
822                 log_text ("CACAO terminated by shutdown");
823                 if (statistics)
824                         print_stats ();
825                 if (getcompilingtime)
826                         print_times ();
827                 mem_usagelog(0);
828                 sprintf (logtext, "Exit status: %d\n", (int) status);
829                 dolog();
830                 }
831
832         exit(status);
833 }
834
835
836 /*
837  * These are local overrides for various environment variables in Emacs.
838  * Please do not remove this and leave it at the end of the file, where
839  * Emacs will automagically detect them.
840  * ---------------------------------------------------------------------
841  * Local variables:
842  * mode: c
843  * indent-tabs-mode: t
844  * c-basic-offset: 4
845  * tab-width: 4
846  * End:
847  */