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