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