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