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