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