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