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