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