c7455a16bd7b8f8ac82f3a0cb21fb8ce7b66ebe2
[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 1150 2004-06-06 13:29:25Z twisti $
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/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/logging.h"
58 #include "toolbox/memory.h"
59 #include "jit/parseRTstats.h"
60 #include "nat/java_io_File.h"            /* required by java_lang_Runtime.h   */
61 #include "nat/java_util_Properties.h"    /* required by java_lang_Runtime.h   */
62 #include "nat/java_lang_Runtime.h"
63 #include "nat/java_lang_Throwable.h"
64
65 #ifdef TYPEINFO_DEBUG_TEST
66 #include "typeinfo.h"
67 #endif
68
69 /* command line option */
70
71 bool verbose = false;
72 bool compileall = false;
73 bool runverbose = false;       /* trace all method invocation                */
74 bool verboseexception = false;
75 bool collectverbose = false;
76
77 bool loadverbose = false;
78 bool linkverbose = false;
79 bool initverbose = false;
80
81 bool opt_rt = false;           /* true if RTA parse should be used     RT-CO */
82 bool opt_xta = false;          /* true if XTA parse should be used    XTA-CO */
83 bool opt_vta = false;          /* true if VTA parse should be used    VTA-CO */
84
85 bool opt_liberalutf = false;   /* Don't check overlong UTF-8 sequences       */
86
87 bool showmethods = false;
88 bool showconstantpool = false;
89 bool showutf = false;
90
91 bool compileverbose =  false;  /* trace compiler actions                     */
92 bool showstack = false;
93 bool showdisassemble = false;  /* generate disassembler listing              */
94 bool showddatasegment = false; /* generate data segment listing              */
95 bool showintermediate = false; /* generate intermediate code listing         */
96
97 bool useinlining = false;      /* use method inlining                        */
98 bool inlinevirtuals = false;   /* inline unique virtual methods              */
99 bool inlineexceptions = false; /* inline methods, that contain excptions     */
100 bool inlineparamopt = false;   /* optimize parameter passing to inlined methods */
101 bool inlineoutsiders = false;  /* inline methods, that are not member of the invoker's class */
102
103 bool checkbounds = true;       /* check array bounds                         */
104 bool checknull = true;         /* check null pointers                        */
105 bool opt_noieee = false;       /* don't implement ieee compliant floats      */
106 bool checksync = true;         /* do synchronization                         */
107 bool opt_loops = false;        /* optimize array accesses in loops           */
108
109 bool makeinitializations = true;
110
111 bool getloadingtime = false;   /* to measure the runtime                     */
112 s8 loadingtime = 0;
113
114 bool getcompilingtime = false; /* compute compile time                       */
115 s8 compilingtime = 0;          /* accumulated compile time                   */
116
117 int has_ext_instr_set = 0;     /* has instruction set extensions */
118
119 bool opt_stat = false;
120
121 bool opt_verify = true;        /* true if classfiles should be verified      */
122
123 bool opt_eager = false;
124
125 char *mainstring;
126 static classinfo *mainclass;
127
128 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
129 void **stackbottom = 0;
130 #endif
131
132
133 /* internal function: get_opt *************************************************
134         
135         decodes the next command line option
136         
137 ******************************************************************************/
138
139 #define OPT_DONE       -1
140 #define OPT_ERROR       0
141 #define OPT_IGNORE      1
142
143 #define OPT_CLASSPATH   2
144 #define OPT_D           3
145 #define OPT_MS          4
146 #define OPT_MX          5
147 #define OPT_VERBOSE1    6
148 #define OPT_VERBOSE     7
149 #define OPT_VERBOSEGC   8
150 #define OPT_VERBOSECALL 9
151 #define OPT_NOIEEE      10
152 #define OPT_SOFTNULL    11
153 #define OPT_TIME        12
154 #define OPT_STAT        13
155 #define OPT_LOG         14
156 #define OPT_CHECK       15
157 #define OPT_LOAD        16
158 #define OPT_METHOD      17
159 #define OPT_SIGNATURE   18
160 #define OPT_SHOW        19
161 #define OPT_ALL         20
162 #define OPT_OLOOP       24
163 #define OPT_INLINING    25
164 #define OPT_RT          26
165 #define OPT_XTA         27 
166 #define OPT_VTA         28
167 #define OPT_VERBOSETC   29
168 #define OPT_NOVERIFY    30
169 #define OPT_LIBERALUTF  31
170 #define OPT_VERBOSEEXCEPTION 32
171 #define OPT_EAGER            33
172
173
174 struct {char *name; bool arg; int value;} opts[] = {
175         {"classpath",        true,   OPT_CLASSPATH},
176         {"D",                true,   OPT_D},
177         {"ms",               true,   OPT_MS},
178         {"mx",               true,   OPT_MX},
179         {"noasyncgc",        false,  OPT_IGNORE},
180         {"noverify",         false,  OPT_NOVERIFY},
181         {"liberalutf",       false,  OPT_LIBERALUTF},
182         {"oss",              true,   OPT_IGNORE},
183         {"ss",               true,   OPT_IGNORE},
184         {"v",                false,  OPT_VERBOSE1},
185         {"verbose",          false,  OPT_VERBOSE},
186         {"verbosegc",        false,  OPT_VERBOSEGC},
187         {"verbosecall",      false,  OPT_VERBOSECALL},
188         {"verboseexception", false,  OPT_VERBOSEEXCEPTION},
189 #ifdef TYPECHECK_VERBOSE
190         {"verbosetc",        false,  OPT_VERBOSETC},
191 #endif
192 #if defined(__ALPHA__)
193         {"noieee",           false,  OPT_NOIEEE},
194 #endif
195         {"softnull",         false,  OPT_SOFTNULL},
196         {"time",             false,  OPT_TIME},
197         {"stat",             false,  OPT_STAT},
198         {"log",              true,   OPT_LOG},
199         {"c",                true,   OPT_CHECK},
200         {"l",                false,  OPT_LOAD},
201     { "eager",            false,  OPT_EAGER },
202         {"m",                true,   OPT_METHOD},
203         {"sig",              true,   OPT_SIGNATURE},
204         {"s",                true,   OPT_SHOW},
205         {"all",              false,  OPT_ALL},
206         {"oloop",            false,  OPT_OLOOP},
207         {"i",                    true,   OPT_INLINING},
208         {"rt",               false,  OPT_RT},
209         {"xta",              false,  OPT_XTA},
210         {"vta",              false,  OPT_VTA},
211         {NULL,               false,  0}
212 };
213
214 static int opt_ind = 1;
215 static char *opt_arg;
216
217
218 static int get_opt(int argc, char **argv)
219 {
220         char *a;
221         int i;
222         
223         if (opt_ind >= argc) return OPT_DONE;
224         
225         a = argv[opt_ind];
226         if (a[0] != '-') return OPT_DONE;
227
228         for (i = 0; opts[i].name; i++) {
229                 if (!opts[i].arg) {
230                         if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
231                                 opt_ind++;
232                                 return opts[i].value;
233                         }
234
235                 } else {
236                         if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
237                                 opt_ind++;
238                                 if (opt_ind < argc) {
239                                         opt_arg = argv[opt_ind];
240                                         opt_ind++;
241                                         return opts[i].value;
242                                 }
243                                 return OPT_ERROR;
244
245                         } else {
246                                 size_t l = strlen(opts[i].name);
247                                 if (strlen(a + 1) > l) {
248                                         if (memcmp(a + 1, opts[i].name, l) == 0) {
249                                                 opt_ind++;
250                                                 opt_arg = a + 1 + l;
251                                                 return opts[i].value;
252                                         }
253                                 }
254                         }
255                 }
256         } /* end for */ 
257
258         return OPT_ERROR;
259 }
260
261
262 /******************** interne Function: print_usage ************************
263
264 Prints the correct usage syntax to stdout.
265
266 ***************************************************************************/
267
268 static void print_usage()
269 {
270         printf("USAGE: cacao [options] classname [program arguments]\n");
271         printf("Options:\n");
272         printf("          -classpath path ...... specify a path to look for classes\n");
273         printf("          -Dpropertyname=value . add an entry to the property list\n");
274         printf("          -mx maxmem[k|m] ...... specify the size for the heap\n");
275         printf("          -ms initmem[k|m] ..... specify the initial size for the heap\n");
276         printf("          -v ................... write state-information\n");
277         printf("          -verbose ............. write more information\n");
278         printf("          -verbosegc ........... write message for each GC\n");
279         printf("          -verbosecall ......... write message for each call\n");
280         printf("          -verboseexception .... write message for each step of stack unwinding\n");
281 #ifdef TYPECHECK_VERBOSE
282         printf("          -verbosetc ........... write debug messages while typechecking\n");
283 #endif
284 #if defined(__ALPHA__)
285         printf("          -noieee .............. don't use ieee compliant arithmetic\n");
286 #endif
287         printf("          -noverify ............ don't verify classfiles\n");
288         printf("          -liberalutf........... don't warn about overlong UTF-8 sequences\n");
289         printf("          -softnull ............ use software nullpointer check\n");
290         printf("          -time ................ measure the runtime\n");
291         printf("          -stat ................ detailed compiler statistics\n");
292         printf("          -log logfile ......... specify a name for the logfile\n");
293         printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
294         printf("                  s(ync) ....... don't check for synchronization\n");
295         printf("          -oloop ............... optimize array accesses in loops\n"); 
296         printf("          -l ................... don't start the class after loading\n");
297         printf("          -eager                 perform eager class loading and linking\n");
298         printf("          -all ................. compile all methods, no execution\n");
299         printf("          -m ................... compile only a specific method\n");
300         printf("          -sig ................. specify signature for a specific method\n");
301         printf("          -s(how)a(ssembler) ... show disassembled listing\n");
302         printf("                 c(onstants) ... show the constant pool\n");
303         printf("                 d(atasegment).. show data segment listing\n");
304         printf("                 i(ntermediate). show intermediate representation\n");
305         printf("                 m(ethods)...... show class fields and methods\n");
306         printf("                 u(tf) ......... show the utf - hash\n");
307         printf("          -i     n ............. activate inlining\n");
308         printf("                 v ............. inline virtual methods\n");
309         printf("                 e ............. inline methods with exceptions\n");
310         printf("                 p ............. optimize argument renaming\n");
311         printf("                 o ............. inline methods of foreign classes\n");
312         printf("          -rt .................. use rapid type analysis\n");
313         printf("          -xta ................. use x type analysis\n");
314         printf("          -vta ................. use variable type analysis\n");
315 }   
316
317
318 /***************************** Function: print_times *********************
319
320         Prints a summary of CPU time usage.
321
322 **************************************************************************/
323
324 static void print_times()
325 {
326         s8 totaltime = getcputime();
327         s8 runtime = totaltime - loadingtime - compilingtime;
328         char logtext[MAXLOGTEXT];
329
330 #if defined(__I386__) || defined(__POWERPC__)
331         sprintf(logtext, "Time for loading classes: %lld secs, %lld millis",
332 #else
333         sprintf(logtext, "Time for loading classes: %ld secs, %ld millis",
334 #endif
335                         loadingtime / 1000000, (loadingtime % 1000000) / 1000);
336         log_text(logtext);
337
338 #if defined(__I386__) || defined(__POWERPC__) 
339         sprintf(logtext, "Time for compiling code:  %lld secs, %lld millis",
340 #else
341         sprintf(logtext, "Time for compiling code:  %ld secs, %ld millis",
342 #endif
343                         compilingtime / 1000000, (compilingtime % 1000000) / 1000);
344         log_text(logtext);
345
346 #if defined(__I386__) || defined(__POWERPC__) 
347         sprintf(logtext, "Time for running program: %lld secs, %lld millis",
348 #else
349         sprintf(logtext, "Time for running program: %ld secs, %ld millis",
350 #endif
351                         runtime / 1000000, (runtime % 1000000) / 1000);
352         log_text(logtext);
353
354 #if defined(__I386__) || defined(__POWERPC__) 
355         sprintf(logtext, "Total time: %lld secs, %lld millis",
356 #else
357         sprintf(logtext, "Total time: %ld secs, %ld millis",
358 #endif
359                         totaltime / 1000000, (totaltime % 1000000) / 1000);
360         log_text(logtext);
361 }
362
363
364 /***************************** Function: print_stats *********************
365
366         outputs detailed compiler statistics
367
368 **************************************************************************/
369
370 static void print_stats()
371 {
372         char logtext[MAXLOGTEXT];
373
374         sprintf(logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
375         log_text(logtext);
376         sprintf(logtext, "Number of compiled Methods: %d", count_methods);
377         log_text(logtext);
378         sprintf(logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
379         log_text(logtext);
380         sprintf(logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
381         log_text(logtext);
382         sprintf(logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
383         log_text(logtext);
384         sprintf(logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
385         log_text(logtext);
386         sprintf(logtext, "Size of compiled JavaVM-Instructions:   %d(%d)", count_javacodesize,
387                         count_javacodesize - count_methods * 18);
388         log_text(logtext);
389         sprintf(logtext, "Size of compiled Exception Tables:      %d", count_javaexcsize);
390         log_text(logtext);
391         sprintf(logtext, "Value of extended instruction set var:  %d", has_ext_instr_set);
392         log_text(logtext);
393         sprintf(logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
394         log_text(logtext);
395         sprintf(logtext, "Number of Spills: %d", count_spills);
396         log_text(logtext);
397         sprintf(logtext, "Number of Activ    Pseudocommands: %5d", count_pcmd_activ);
398         log_text(logtext);
399         sprintf(logtext, "Number of Drop     Pseudocommands: %5d", count_pcmd_drop);
400         log_text(logtext);
401         sprintf(logtext, "Number of Const    Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
402         log_text(logtext);
403         sprintf(logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
404         log_text(logtext);
405         sprintf(logtext, "Number of Move     Pseudocommands: %5d", count_pcmd_move);
406         log_text(logtext);
407         sprintf(logtext, "Number of Load     Pseudocommands: %5d", count_load_instruction);
408         log_text(logtext);
409         sprintf(logtext, "Number of Store    Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
410         log_text(logtext);
411         sprintf(logtext, "Number of OP       Pseudocommands: %5d", count_pcmd_op);
412         log_text(logtext);
413         sprintf(logtext, "Number of DUP      Pseudocommands: %5d", count_dup_instruction);
414         log_text(logtext);
415         sprintf(logtext, "Number of Mem      Pseudocommands: %5d", count_pcmd_mem);
416         log_text(logtext);
417         sprintf(logtext, "Number of Method   Pseudocommands: %5d", count_pcmd_met);
418         log_text(logtext);
419         sprintf(logtext, "Number of Branch   Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
420                         count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
421         log_text(logtext);
422         sprintf(logtext, "Number of Table    Pseudocommands: %5d", count_pcmd_table);
423         log_text(logtext);
424         sprintf(logtext, "Number of Useful   Pseudocommands: %5d", count_pcmd_table +
425                         count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
426         log_text(logtext);
427         sprintf(logtext, "Number of Null Pointer Checks:     %5d", count_check_null);
428         log_text(logtext);
429         sprintf(logtext, "Number of Array Bound Checks:      %5d", count_check_bound);
430         log_text(logtext);
431         sprintf(logtext, "Number of Try-Blocks: %d", count_tryblocks);
432         log_text(logtext);
433         sprintf(logtext, "Maximal count of stack elements:   %d", count_max_new_stack);
434         log_text(logtext);
435         sprintf(logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
436         log_text(logtext);
437         sprintf(logtext, "Distribution of stack sizes at block boundary");
438         log_text(logtext);
439         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
440         log_text(logtext);
441         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
442                         count_block_stack[1], count_block_stack[2], count_block_stack[3], count_block_stack[4],
443                         count_block_stack[5], count_block_stack[6], count_block_stack[7], count_block_stack[8],
444                         count_block_stack[9], count_block_stack[10]);
445         log_text(logtext);
446         sprintf(logtext, "Distribution of store stack depth");
447         log_text(logtext);
448         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
449         log_text(logtext);
450         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
451                         count_store_depth[1], count_store_depth[2], count_store_depth[3], count_store_depth[4],
452                         count_store_depth[5], count_store_depth[6], count_store_depth[7], count_store_depth[8],
453                         count_store_depth[9], count_store_depth[10]);
454         log_text(logtext);
455         sprintf(logtext, "Distribution of store creator chains first part");
456         log_text(logtext);
457         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9  ");
458         log_text(logtext);
459         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
460                         count_store_length[1], count_store_length[2], count_store_length[3], count_store_length[4],
461                         count_store_length[5], count_store_length[6], count_store_length[7], count_store_length[8],
462                         count_store_length[9]);
463         log_text(logtext);
464         sprintf(logtext, "Distribution of store creator chains second part");
465         log_text(logtext);
466         sprintf(logtext, "   10   11   12   13   14   15   16   17   18   19  >=20");
467         log_text(logtext);
468         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
469                         count_store_length[11], count_store_length[12], count_store_length[13], count_store_length[14],
470                         count_store_length[15], count_store_length[16], count_store_length[17], count_store_length[18],
471                         count_store_length[19], count_store_length[20]);
472         log_text(logtext);
473         sprintf(logtext, "Distribution of analysis iterations");
474         log_text(logtext);
475         sprintf(logtext, "    1    2    3    4    >=5");
476         log_text(logtext);
477         sprintf(logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0], count_analyse_iterations[1],
478                         count_analyse_iterations[2], count_analyse_iterations[3], count_analyse_iterations[4]);
479         log_text(logtext);
480         sprintf(logtext, "Distribution of basic blocks per method");
481         log_text(logtext);
482         sprintf(logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75  >75");
483         log_text(logtext);
484         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
485                         count_method_bb_distribution[1], count_method_bb_distribution[2], count_method_bb_distribution[3],
486                         count_method_bb_distribution[4], count_method_bb_distribution[5], count_method_bb_distribution[6],
487                         count_method_bb_distribution[7], count_method_bb_distribution[8]);
488         log_text(logtext);
489         sprintf(logtext, "Distribution of basic block sizes");
490         log_text(logtext);
491         sprintf(logtext,
492                          "  0    1    2    3    4   5   6   7   8   9 <13 <15 <17 <19 <21 <26 <31 >30");
493         log_text(logtext);
494         sprintf(logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
495                         count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
496                         count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
497                         count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
498                         count_block_size_distribution[9], count_block_size_distribution[10], count_block_size_distribution[11],
499                         count_block_size_distribution[12], count_block_size_distribution[13], count_block_size_distribution[14],
500                         count_block_size_distribution[15], count_block_size_distribution[16], count_block_size_distribution[17]);
501         log_text(logtext);
502         sprintf(logtext, "Size of Code Area (Kb):  %10.3f", (float) count_code_len / 1024);
503         log_text(logtext);
504         sprintf(logtext, "Size of data Area (Kb):  %10.3f", (float) count_data_len / 1024);
505         log_text(logtext);
506         sprintf(logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
507         log_text(logtext);
508         sprintf(logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
509         log_text(logtext);
510         sprintf(logtext, "Size of Vftbl (Kb):      %10.3f", (float) count_vftbl_len / 1024);
511         log_text(logtext);
512         sprintf(logtext, "Size of comp stub (Kb):  %10.3f", (float) count_cstub_len / 1024);
513         log_text(logtext);
514         sprintf(logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
515         log_text(logtext);
516         sprintf(logtext, "Size of Utf (Kb):        %10.3f", (float) count_utf_len / 1024);
517         log_text(logtext);
518         sprintf(logtext, "Size of VMCode (Kb):     %10.3f(%d)", (float) count_vmcode_len / 1024,
519                         count_vmcode_len - 18 * count_all_methods);
520         log_text(logtext);
521         sprintf(logtext, "Size of ExTable (Kb):    %10.3f", (float) count_extable_len / 1024);
522         log_text(logtext);
523         sprintf(logtext, "Number of class loads:   %d", count_class_loads);
524         log_text(logtext);
525         sprintf(logtext, "Number of class inits:   %d", count_class_inits);
526         log_text(logtext);
527         sprintf(logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
528         log_text(logtext);
529
530         sprintf(logtext, "Calls of utf_new: %22d", count_utf_new);
531         log_text(logtext);
532         sprintf(logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
533         log_text(logtext);
534 }
535
536
537 #ifdef TYPECHECK_STATISTICS
538 void typecheck_print_statistics(FILE *file);
539 #endif
540
541
542 /*
543  * void exit_handler(void)
544  * -----------------------
545  * The exit_handler function is called upon program termination to shutdown
546  * the various subsystems and release the resources allocated to the VM.
547  */
548 void exit_handler(void)
549 {
550         /********************* Print debug tables ************************/
551                                 
552         if (showmethods) class_showmethods(mainclass);
553         if (showconstantpool) class_showconstantpool(mainclass);
554         if (showutf) utf_show();
555
556 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
557         clear_thread_flags();           /* restores standard file descriptor
558                                        flags */
559 #endif
560
561         /************************ Free all resources *******************/
562
563         /*heap_close();*/               /* must be called before compiler_close and
564                                        loader_close because finalization occurs
565                                        here */
566
567         loader_close();
568         tables_close(literalstring_free);
569
570         if (verbose || getcompilingtime || opt_stat) {
571                 log_text("CACAO terminated");
572                 if (opt_stat) {
573                         print_stats();
574 #ifdef TYPECHECK_STATISTICS
575                         typecheck_print_statistics(get_logfile());
576 #endif
577                 }
578                 if (getcompilingtime)
579                         print_times();
580                 mem_usagelog(1);
581         }
582 }
583
584
585 /************************** Function: main *******************************
586
587    The main program.
588    
589 **************************************************************************/
590
591 int main(int argc, char **argv)
592 {
593         s4 i, j;
594         void *dummy;
595         
596         /********** interne (nur fuer main relevante Optionen) **************/
597    
598         char logfilename[200] = "";
599         u4 heapmaxsize = 64 * 1024 * 1024;
600         u4 heapstartsize = 200 * 1024;
601         char *cp;
602         char classpath[500] = ".";
603         bool startit = true;
604         char *specificmethodname = NULL;
605         char *specificsignature = NULL;
606
607 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
608         stackbottom = &dummy;
609 #endif
610         
611         if (0 != atexit(exit_handler)) 
612                 throw_cacao_exception_exit(string_java_lang_InternalError,
613                                                                    "unable to register exit_handler");
614
615
616         /************ Collect info from the environment ************************/
617
618         cp = getenv("CLASSPATH");
619         if (cp) {
620                 strcpy(classpath, cp);
621         }
622
623         /***************** Interpret the command line *****************/
624    
625         checknull = false;
626         opt_noieee = false;
627
628         while ((i = get_opt(argc, argv)) != OPT_DONE) {
629                 switch (i) {
630                 case OPT_IGNORE: break;
631                         
632                 case OPT_CLASSPATH:    
633                         strcpy(classpath + strlen(classpath), ":");
634                         strcpy(classpath + strlen(classpath), opt_arg);
635                         break;
636                                 
637                 case OPT_D:
638                         {
639                                 int n;
640                                 int l = strlen(opt_arg);
641                                 for (n = 0; n < l; n++) {
642                                         if (opt_arg[n] == '=') {
643                                                 opt_arg[n] = '\0';
644                                                 attach_property(opt_arg, opt_arg + n + 1);
645                                                 goto didit;
646                                         }
647                                 }
648                                 print_usage();
649                                 exit(10);
650                                         
651                         didit: ;
652                         }       
653                         break;
654
655                 case OPT_MS:
656                 case OPT_MX:
657                         if (opt_arg[strlen(opt_arg) - 1] == 'k') {
658                                 j = 1024 * atoi(opt_arg);
659
660                         } else if (opt_arg[strlen(opt_arg) - 1] == 'm') {
661                                 j = 1024 * 1024 * atoi(opt_arg);
662
663                         } else j = atoi(opt_arg);
664
665                         if (i == OPT_MX) heapmaxsize = j;
666                         else heapstartsize = j;
667                         break;
668
669                 case OPT_VERBOSE1:
670                         verbose = true;
671                         break;
672
673                 case OPT_VERBOSE:
674                         verbose = true;
675                         loadverbose = true;
676                         linkverbose = true;
677                         initverbose = true;
678                         compileverbose = true;
679                         break;
680
681                 case OPT_VERBOSEEXCEPTION:
682                         verboseexception = true;
683                         break;
684
685                 case OPT_VERBOSEGC:
686                         collectverbose = true;
687                         break;
688
689 #ifdef TYPECHECK_VERBOSE
690                 case OPT_VERBOSETC:
691                         typecheckverbose = true;
692                         break;
693 #endif
694                                 
695                 case OPT_VERBOSECALL:
696                         runverbose = true;
697                         break;
698                                 
699                 case OPT_NOIEEE:
700                         opt_noieee = true;
701                         break;
702
703                 case OPT_NOVERIFY:
704                         opt_verify = false;
705                         break;
706
707                 case OPT_LIBERALUTF:
708                         opt_liberalutf = true;
709                         break;
710
711                 case OPT_SOFTNULL:
712                         checknull = true;
713                         break;
714
715                 case OPT_TIME:
716                         getcompilingtime = true;
717                         getloadingtime = true;
718                         break;
719                                         
720                 case OPT_STAT:
721                         opt_stat = true;
722                         break;
723                                         
724                 case OPT_LOG:
725                         strcpy(logfilename, opt_arg);
726                         break;
727                         
728                 case OPT_CHECK:
729                         for (j = 0; j < strlen(opt_arg); j++) {
730                                 switch (opt_arg[j]) {
731                                 case 'b':
732                                         checkbounds = false;
733                                         break;
734                                 case 's':
735                                         checksync = false;
736                                         break;
737                                 default:
738                                         print_usage();
739                                         exit(10);
740                                 }
741                         }
742                         break;
743                         
744                 case OPT_LOAD:
745                         startit = false;
746                         makeinitializations = false;
747                         break;
748
749                 case OPT_EAGER:
750                         opt_eager = true;
751                         break;
752
753                 case OPT_METHOD:
754                         startit = false;
755                         specificmethodname = opt_arg;                   
756                         makeinitializations = false;
757                         break;
758                         
759                 case OPT_SIGNATURE:
760                         specificsignature = opt_arg;                    
761                         break;
762                         
763                 case OPT_ALL:
764                         compileall = true;              
765                         startit = false;
766                         makeinitializations = false;
767                         break;
768                         
769                 case OPT_SHOW:       /* Display options */
770                         for (j = 0; j < strlen(opt_arg); j++) {         
771                                 switch (opt_arg[j]) {
772                                 case 'a':
773                                         showdisassemble = true;
774                                         compileverbose=true;
775                                         break;
776                                 case 'c':
777                                         showconstantpool = true;
778                                         break;
779                                 case 'd':
780                                         showddatasegment = true;
781                                         break;
782                                 case 'i':
783                                         showintermediate = true;
784                                         compileverbose = true;
785                                         break;
786                                 case 'm':
787                                         showmethods = true;
788                                         break;
789                                 case 'u':
790                                         showutf = true;
791                                         break;
792                                 default:
793                                         print_usage();
794                                         exit(10);
795                                 }
796                         }
797                         break;
798                         
799                 case OPT_OLOOP:
800                         opt_loops = true;
801                         break;
802
803                 case OPT_INLINING:
804                         for (j = 0; j < strlen(opt_arg); j++) {         
805                                 switch (opt_arg[j]) {
806                                 case 'n':
807                                         useinlining = true;
808                                         break;
809                                 case 'v':
810                                         inlinevirtuals = true;
811                                         break;
812                                 case 'e':
813                                         inlineexceptions = true;
814                                         break;
815                                 case 'p':
816                                         inlineparamopt = true;
817                                         break;
818                                 case 'o':
819                                         inlineoutsiders = true;
820                                         break;
821                                 default:
822                                         print_usage();
823                                         exit(10);
824                                 }
825                         }
826                         break;
827
828                 case OPT_RT:
829                         opt_rt = true;
830                         break;
831
832                 case OPT_XTA:
833                         opt_xta = false; /**not yet **/
834                         break;
835
836                 case OPT_VTA:
837                         /***opt_vta = true; not yet **/
838                         break;
839
840                 default:
841                         print_usage();
842                         exit(10);
843                 }
844         }
845    
846    
847         if (opt_ind >= argc) {
848                 print_usage();
849                 exit(10);
850         }
851
852         mainstring = argv[opt_ind++];
853         for (i = strlen(mainstring) - 1; i >= 0; i--) {     /* Transform dots into slashes */
854                 if (mainstring[i] == '.') mainstring[i] = '/';  /* in the class name */
855         }
856
857
858         /**************************** Program start *****************************/
859
860         log_init(logfilename);
861         if (verbose)
862                 log_text("CACAO started -------------------------------------------------------");
863
864         /* initialize the garbage collector */
865         gc_init(heapmaxsize, heapstartsize);
866
867         native_setclasspath(classpath);
868                 
869         tables_init();
870         suck_init(classpath);
871
872 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
873         initThreadsEarly();
874 #endif
875
876         loader_init((u1 *) &dummy);
877
878         native_loadclasses();
879
880         jit_init();
881
882 #if defined(USE_THREADS)
883         initThreads((u1*) &dummy);
884 #endif
885
886
887         /************************* Start worker routines ********************/
888
889         if (startit) {
890                 methodinfo *mainmethod;
891                 java_objectarray *a; 
892
893                 /* create, load and link the main class */
894                 mainclass = class_new(utf_new_char(mainstring));
895
896                 if (!class_load(mainclass))
897                         throw_exception_exit();
898
899                 if (!class_link(mainclass))
900                         throw_exception_exit();
901
902                 mainmethod = class_resolveclassmethod(mainclass,
903                                                                                           utf_new_char("main"), 
904                                                                                           utf_new_char("([Ljava/lang/String;)V"),
905                                                                                           mainclass,
906                                                                                           false);
907
908                 /* problems with main method? */
909 /*              if (*exceptionptr) */
910 /*                      throw_exception_exit(); */
911
912                 /* there is no main method or it isn't static */
913                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
914                         *exceptionptr =
915                                 new_exception_message(string_java_lang_NoSuchMethodError,
916                                                                           "main");
917                         throw_exception_exit();
918                 }
919
920                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
921                 for (i = opt_ind; i < argc; i++) {
922                         a->data[i - opt_ind] = 
923                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
924                 }
925
926 #ifdef TYPEINFO_DEBUG_TEST
927                 /* test the typeinfo system */
928                 typeinfo_test();
929 #endif
930                 /*class_showmethods(currentThread->group->header.vftbl->class); */
931
932                 *threadrootmethod = mainmethod;
933
934                 /* here we go... */
935                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
936
937                 /* exception occurred? */
938                 if (*exceptionptr)
939                         throw_exception_exit();
940
941 #if defined(USE_THREADS)
942 #if defined(NATIVE_THREADS)
943                 joinAllThreads();
944 #else
945                 killThread(currentThread);
946 #endif
947 #endif
948
949                 /* now exit the JavaVM */
950
951                 cacao_exit(0);
952         }
953
954         /************* If requested, compile all methods ********************/
955
956         if (compileall) {
957                 classinfo *c;
958                 methodinfo *m;
959                 u4 slot;
960                 s4 i;
961
962                 /* create all classes found in the classpath */
963                 /* XXX currently only works with zip/jar's */
964                 create_all_classes();
965
966                 /* load and link all classes */
967                 for (slot = 0; slot < class_hash.size; slot++) {
968                         c = class_hash.ptr[slot];
969
970                         while (c) {
971                                 if (!c->loaded)
972                                         class_load(c);
973
974                                 if (!c->linked)
975                                         class_link(c);
976
977                                 /* compile all class methods */
978                                 for (i = 0; i < c->methodscount; i++) {
979                                         m = &(c->methods[i]);
980                                         if (m->jcode) {
981                                                 (void) jit_compile(m);
982                                         }
983                                 }
984
985                                 c = c->hashlink;
986                         }
987                 }
988         }
989
990
991         /******** If requested, compile a specific method ***************/
992
993         if (specificmethodname) {
994                 methodinfo *m;
995
996                 /* create, load and link the main class */
997                 mainclass = class_new(utf_new_char(mainstring));
998                 class_load(mainclass);
999
1000                 if (*exceptionptr)
1001                         throw_exception_exit();
1002
1003                 class_link(mainclass);
1004
1005                 if (*exceptionptr)
1006                         throw_exception_exit();
1007
1008                 if (specificsignature) {
1009                         m = class_resolveclassmethod(mainclass,
1010                                                                                  utf_new_char(specificmethodname),
1011                                                                                  utf_new_char(specificsignature),
1012                                                                                  mainclass,
1013                                                                                  false);
1014                 } else {
1015                         m = class_resolveclassmethod(mainclass,
1016                                                                                  utf_new_char(specificmethodname),
1017                                                                                  NULL,
1018                                                                                  mainclass,
1019                                                                                  false);
1020                 }
1021
1022                 if (!m) {
1023                         char message[MAXLOGTEXT];
1024                         sprintf(message, "%s%s", specificmethodname,
1025                                         specificmethodname ? specificmethodname : "");
1026
1027                         *exceptionptr =
1028                                 new_exception_message(string_java_lang_NoSuchMethodException,
1029                                                                           message);
1030                                                                                  
1031                         throw_exception_exit();
1032                 }
1033                 
1034                 jit_compile(m);
1035         }
1036
1037         cacao_shutdown(0);
1038
1039         /* keep compiler happy */
1040
1041         return 0;
1042 }
1043
1044
1045 /* cacao_exit ******************************************************************
1046
1047    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
1048
1049 *******************************************************************************/
1050
1051 void cacao_exit(s4 status)
1052 {
1053         classinfo *c;
1054         methodinfo *m;
1055         java_lang_Runtime *rt;
1056
1057         /* class should already be loaded, but who knows... */
1058
1059         c = class_new(utf_new_char("java/lang/Runtime"));
1060
1061         if (!class_load(c))
1062                 throw_exception_exit();
1063
1064         if (!class_link(c))
1065                 throw_exception_exit();
1066
1067         /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
1068
1069         m = class_resolveclassmethod(c,
1070                                                                  utf_new_char("getRuntime"),
1071                                                                  utf_new_char("()Ljava/lang/Runtime;"),
1072                                                                  class_java_lang_Object,
1073                                                                  true);
1074
1075         if (!m)
1076                 throw_exception_exit();
1077
1078         rt = (java_lang_Runtime *) asm_calljavafunction(m,
1079                                                                                                         (void *) 0,
1080                                                                                                         NULL,
1081                                                                                                         NULL,
1082                                                                                                         NULL);
1083
1084         /* exception occurred? */
1085
1086         if (*exceptionptr)
1087                 throw_exception_exit();
1088
1089         /* then call Runtime.exit(I)V */
1090
1091         m = class_resolveclassmethod(c,
1092                                                                  utf_new_char("exit"),
1093                                                                  utf_new_char("(I)V"),
1094                                                                  class_java_lang_Object,
1095                                                                  true);
1096         
1097         if (!m)
1098                 throw_exception_exit();
1099
1100         asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
1101
1102         /* this should never happen */
1103
1104         throw_cacao_exception_exit(string_java_lang_InternalError,
1105                                                            "Problems with Runtime.exit(I)V");
1106 }
1107
1108
1109 /*************************** Shutdown function *********************************
1110
1111         Terminates the system immediately without freeing memory explicitly (to be
1112         used only for abnormal termination)
1113         
1114 *******************************************************************************/
1115
1116 void cacao_shutdown(s4 status)
1117 {
1118         /**** RTAprint ***/
1119
1120         if (verbose || getcompilingtime || opt_stat) {
1121                 log_text("CACAO terminated by shutdown");
1122                 if (opt_stat)
1123                         print_stats();
1124                 if (getcompilingtime)
1125                         print_times();
1126                 mem_usagelog(0);
1127                 dolog("Exit status: %d\n", (int) status);
1128         }
1129
1130         exit(status);
1131 }
1132
1133
1134 /*
1135  * These are local overrides for various environment variables in Emacs.
1136  * Please do not remove this and leave it at the end of the file, where
1137  * Emacs will automagically detect them.
1138  * ---------------------------------------------------------------------
1139  * Local variables:
1140  * mode: c
1141  * indent-tabs-mode: t
1142  * c-basic-offset: 4
1143  * tab-width: 4
1144  * End:
1145  */