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