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